Чтение текстового документа символ за символом - PullRequest
1 голос
/ 02 июля 2010

Я читаю текстовый файл символ за символом, используя ifstream infile.get () в бесконечном цикле while.

Он находится внутри бесконечного цикла while и должен выйти из него, как только будет достигнуто условие конца файла. (EOF). Сам цикл while находится внутри функции типа void.

Вот псевдокод:

void function (...) {
    while(true) {
        ...
        if ( (ch = infile.get()) == EOF) {return;}
        ...
    }
}

Когда я «cout» символы на экране, он проходит через весь символ, а затем продолжает работать, выводя то, что выглядит как пробел, то есть он никогда не ломается. Понятия не имею почему. Есть идеи?

Ответы [ 4 ]

2 голосов
/ 02 июля 2010

В C ++ вы не сравниваете возвращаемое значение с EOF. Вместо этого вы можете использовать потоковую функцию, такую ​​как good(), чтобы проверить, можно ли прочитать больше данных. Примерно так:

while (infile.good()) {
  ch = infile.get();
  // ...
}
1 голос
/ 02 июля 2010

Одна идиома, которая позволяет относительно легко читать из файла и правильно определять конец файла, - это объединение чтения и тестирования в одно атомарное событие, такое как:

while (infile >> ch)

или

while (std::getline(infile, instring))

Конечно, вы также должны рассмотреть возможность использования стандартного алгоритма, такого как copy:

std::copy(std::istream_iterator<char>(infile),
          std::istream_iterator<char>(),
          std::ostream_itertror<char>(std::cout, "\n"));

Одна небольшая заметка: по умолчанию чтение с >> пропустит пробел. Когда вы делаете посимвольный ввод / обработку, вы обычно этого не хотите. К счастью, отключить это довольно просто:

infile.unsetf(std::ios_base::skipws);
1 голос
/ 02 июля 2010

попробуйте преобразовать функцию в int и вернуть 1 при достижении EOF

0 голосов
/ 02 июля 2010

Причина, по которой он не работает, заключается в том, что get () возвращает int, но вы используете входные данные как char.

Когда вы присваиваете результат get () для char, это нормально, еслив качестве последнего прочитанного символа был персонаж.НО, если последний прочитанный символ был специальным символом (например, EOF), тогда он будет усечен при назначении на символ, и, следовательно, последующее сравнение с EOF всегда будет неудачным.1006 *

Но следует отметить, что намного проще использовать более стандартный шаблон, где чтение выполняется как часть условия.К сожалению, get () не дает вам такой функциональности.Поэтому нам нужно переключиться на метод, который использует итераторы.

Обратите внимание, что стандартный istream_iterator не будет работать так, как вы ожидаете (так как он игнорирует пробелы).Но вы можете использовать istreambuf_iterator (обратите внимание на buf после istream), который не игнорирует пробелы.

void function (...) 
{
    for(std::istreambuf_iterator<char> loop(infile);
        loop != std::istreambuf_iterator<char>();
        ++loop) 
    {
        char ch = *loop; 
        ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...