Правильное использование проверки конца файла

1,00
р.
При использовании кода
while(!feof(file)) { // Чтение из файла }
в C или
while(!file.eof()) { // Чтение из файла }
в C++ получаются неприятности - лишняя считанная строка, например. Почему? Как правильно проверить, что достигнут конец файла?

Ответ
Признак достижения конца файла выставляется только после неудачной попытки чтения за его концом. Поэтому, если в теле цикла нет проверки, успешно ли выполнено чтение из файла - последнее чтение окажется именно тем неудачным чтением, которое выставит признак достигнутого конца файла (а для вас это будет выглядеть как, например, еще раз считанная последняя строка, если она находилась в буфере для чтения).
Лучше в заголовке цикла while выполнять само чтение с проверкой - например, в программе на C это могло бы выглядеть как
while(fread(&data,sizeof(data),1,file)==1) { // Обработка считанных данных }
/* Или, скажем, while(fgets(buf, bufsize, file)) { .... } */
if (feof(file)) // Достигнут конец файла puts("Ошибка чтения: достигнут конец файла") else if (ferror(file)) { puts("Ошибка чтения файла")
или на C++ - наподобие
for(int n file >> n ) { // Обработка считанного значения n }
if (file.bad()) std::cout << "Ошибка ввода-вывода при чтении<br>" else if (file.eof()) std::cout << "Достигнут конец файла<br>" else if (file.fail()) std::cout << "Неверный формат данных<br>"