Как читать из текстового файла, символ по символу в С++

Мне было интересно, может ли кто-нибудь помочь мне разобраться, как читать из текстового файла в С++, по характеру. Таким образом, у меня может быть цикл while (пока остается текст слева), где я храню следующий символ в текстовом документе в переменной temp, чтобы я мог что-то с этим сделать, а затем повторить процесс со следующим символом. Я знаю, как открыть файл и все, но temp = textFile.getchar(), похоже, не работает. Спасибо заранее.

Ответ 1

Вы можете попробовать что-то вроде:

char ch;
fstream fin("file", fstream::in);
while (fin >> noskipws >> ch) {
    cout << ch; // Or whatever
}

Ответ 2

@cnicutar и @Pete Becker уже указали на возможность использования noskipws/unsetting skipws для чтения символа за раз, не пропуская символы пробела на входе.

Другая возможность - использовать istreambuf_iterator для чтения данных. Наряду с этим я обычно использовал стандартный алгоритм, например std::transform для чтения и обработки.

Например, предположим, что мы хотели сделать кезар-подобный шифр, скопировав его со стандартного ввода на стандартный вывод, но добавив 3 к каждому символу верхнего регистра, поэтому A станет D, B может стать E и т.д. (и в конце он обернется вокруг так XYZ, преобразованный в ABC.

Если бы мы собирались сделать это на C, мы обычно использовали бы цикл вроде этого:

int ch;
while (EOF != (ch = getchar())) {
    if (isupper(ch)) 
        ch = ((ch - 'A') +3) % 26 + 'A';
    putchar(ch);
}

Чтобы сделать то же самое в С++, я бы, скорее всего, написал код следующим образом:

std::transform(std::istreambuf_iterator<char>(std::cin),
               std::istreambuf_iterator<char>(),
               std::ostreambuf_iterator<char>(std::cout),
               [](int ch) { return isupper(ch) ? ((ch - 'A') + 3) % 26 + 'A' : ch;});

Выполняя задание таким образом, вы получаете последовательные символы как значения параметра, переданного (в данном случае) лямбда-функции (хотя вы могли бы использовать явный функтор вместо лямбда, если хотите).

Ответ 3

    //Variables
    char END_OF_FILE = '#';
    char singleCharacter;

    //Get a character from the input file
    inFile.get(singleCharacter);

    //Read the file until it reaches #
    //When read pointer reads the # it will exit loop
    //This requires that you have a # sign as last character in your text file

    while (singleCharacter != END_OF_FILE)
    {
         cout << singleCharacter;
         inFile.get(singleCharacter);
    }

   //If you need to store each character, declare a variable and store it
   //in the while loop.

Ответ 4

Процитировать Bjarne Stroustrup: "Оператор → предназначен для форматированного ввода, то есть для чтения объектов ожидаемого типа и формата. Если это нежелательно, и мы хотим читать символы как символы, а затем исследовать их, мы используйте функции get().

char c;
while (input.get(c))
{
    // do something with c
}

Ответ 5

Re: textFile.getch(), вы это сделали, или у вас есть ссылка, в которой говорится, что она должна работать? Если это последнее, избавитесь от него. Если это первое, не делайте этого. Получите хорошую ссылку.

char ch;
textFile.unsetf(ios_base::skipws);
textFile >> ch;

Ответ 6

Нет причин не использовать C <stdio.h> в С++, и на самом деле это часто оптимальный выбор.

#include <stdio.h>

int
main()  // (void) not necessary in C++
{
    int c;
    while ((c = getchar()) != EOF) {
        // do something with 'c' here
    }
    return 0; // technically not necessary in C++ but still good style
}

Ответ 7

Вот стильная функция С++, которую вы можете использовать для чтения файлов char на char.

void readCharFile(string &filePath) {
    ifstream in(filePath);
    char c;

    if(in.is_open()) {
        while(in.good()) {
            in.get(c);
            // Play with the data
        }
    }

    if(!in.eof() && in.fail())
        cout << "error reading " << filePath << endl;

    in.close();
}

Ответ 8

Предполагая, что temp является char и textFile является производной std::fstream...

Синтаксис, который вы ищете, это

textFile.get( temp );