Проблема 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.
eofбыло быlast_operation_failed_with_eof, что на самом деле ужасно. Я бы сказал, это ошибка в стандартной библиотеке. – VladD May 05 '15 at 18:29// Здесь eof() == false, но мы это не проверяем.- имеется в виду true? – Qwertiy May 05 '15 at 20:17stream_errors, в котором присутствовал бы нужный флаг. – VladD Jan 13 '19 at 13:14operator >>уstd::basic_istream. Если бы>>не менял значение аргумента при ошибке, то при его чтении вstd::cout << value;было бы UB. – tocic Oct 22 '22 at 04:49