Пробелы в конце файла, вызывающие сбой проверки EOF в C ++ - PullRequest
1 голос
/ 27 октября 2009

Я читаю данные из файла, который имеет три столбца. Например, данные будут выглядеть примерно так:

3  START  RED
4  END    RED

Для считывания данных я использую следующую проверку:

while (iFile.peek() != EOF) {
   // read in column 1
   // read in column 2
   // read in column 3
}

Моя проблема в том, что цикл обычно делает дополнительный цикл. Я уверен, что это потому, что многие текстовые редакторы, похоже, ставят пустую строку после последней строки фактического содержания.

Я немного погуглил, искал на SO и обнаружил несколько похожих ситуаций, таких как Чтение из текстового файла до тех пор, пока EOF не повторяет последнюю строку , однако я не мог приспособить решение, данное для решения моя проблема. Есть предложения?

Ответы [ 5 ]

4 голосов
/ 27 октября 2009

EOF - это не прогноз, а состояние ошибки. Следовательно, вы не можете использовать его так, как сейчас, чтобы предсказать, сможете ли вы прочитать столбцы 1, 2 и 3. По этой причине в C ++ часто встречается следующий шаблон:

while (input >> obj1 >> obj2) {
  use(obj1, obj2);
}

Все operator>>(istream& is, T&) возвращают входной поток, и при использовании в логическом контексте поток имеет значение "истина", если последнее извлечение прошло успешно. Тогда можно безопасно использовать извлеченные объекты.

2 голосов
/ 27 октября 2009

Предполагается, iFile является istream:

Вы должны выйти из цикла при любой ошибке , не только при EOF (что можно проверить с помощью iFile.eof(), BTW), потому что это бесконечный цикл, когда любой сбой формата устанавливает поток в плохое состояние, кроме EOF. Обычно необходимо выйти из цикла чтения в середине цикла, после того, как все прочитано (успешно или нет), и до того, как оно введено.

Чтобы убедиться, что больше ничего интересного не произойдет, вы можете после цикла сбросить состояние потока и затем пытаться читать пробельные символы только до тех пор, пока не достигнете EOF:

while( !iFile.eof() )
{
   iFile >> std::ws;
   string line;
   std::getline(iFile,line);
   if(!line.empty()) error(...);
}
0 голосов
/ 27 октября 2009

Возможно, вы посчитаете хорошей идеей обработать пробелы и другие недопустимые данные. Возможно, желательна также некоторая базовая проверка столбцов 1, 2, 3.

0 голосов
/ 27 октября 2009

Не беспокойтесь о числе циклов: просто проверяйте свои данные и обрабатывайте неверные данные.

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

0 голосов
/ 27 октября 2009

Если какое-либо из чтений не удалось (где вы читаете данные столбца), просто вырвитесь из цикла while. Предположительно, вы находитесь в конце файла и читаете последнюю «неправильную» строку

...