Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Почему считается что неправильно писать while (!input_stream.eof())?


В разных источниках говорят что использование std::istream::eof() - это признак плохого кода и что в частности неправильно писать:

while (!input_stream.eof()) {
    input_stream >> value;
    process(value);
}


Что в этом коде не так? Как писать правильно?
    


Ответы

Ответ 1



Проблема std::istream::eof() в том, что он выставляется только после выполнения какой-либо операции чтения. Поэтому происходит следующее: std::ifstream input_stream("empty_file.txt"); // Открываем пустой файл if (!input_stream.eof()) { // eof() == false, т.к. мы еще ничего не читали int value; input_stream >> value; // Пытаемся читать число, а его там нет. // Здесь eof() == true, но мы это не проверяем. std::cout << value; // Выведется 0. } Так что если и вызывать eof(), то это надо делать после операции чтения. Однако, объекты std::istream умеют преобразовываться в bool, а каждая операция чтения возвращает ссылку на std::istream. Поэтому идиоматичный код выглядит следующим образом: while (input_stream >> value) { process(value); } Или для строки: std::string str; while (std::getline(input_stream, str)) { ... } Или сразу для нескольких значений: while (input_stream >> value1 >> value2) { ... } Здесь если при чтении value1 произойдет ошибка, то все последующие операции чтени (т.е. value2) будут игнорироваться, по этому можно читать сразу несколько значений сразу, и уже потом проверять состояние std::istream.

Ответ 2



eof() - это всего лишь функция, которая возвращает true, если обнаружен конец файла А если кто-то ей пользуется после того, как прочитал мусор куда-то, где он не нужен - вот это уже, возможно, плохой код. Например: char value; if (!(input_stream.get(value))) // если поток в ошибочном состоянии { if (input_stream.eof()) // стал ли причиной конец файла { ничего плохого тут не вижу

Комментариев нет:

Отправить комментарий