Путаница с == EOF vs feof

Я открыл файл, поток находится по адресу указателя ptr. Я пытаюсь увидеть, является ли файл пустым. Используя следующее

if (fgetc(ptr) != EOF)

работает, как ожидалось. Если файл пуст, инструкция не выполняется. Если файл не пуст, инструкция не выполняется.

, используя
if (!feof(ptr))

всегда выполняет инструкцию.

Почему это происходит? Есть ли способ использовать feof функции?

4 ответов


есть ли способ, чтобы использовать ?

Да, есть. после функция ввода вернула значение, которое указывает, что у нее больше нет ввода для обработки, вы можете вызвать feof() и/или ferror() чтобы определить, было ли условие вызвано достижением конца входного сигнала или некоторым условием ошибки.

это единственное допустимое использование feof() и ferror() функции.

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


в стандартной библиотеке C "конец файла" не является независимым условием самоопределения. "Конец файла" - это просто набор состояний файла предыдущей операцией чтения. Пока вы не выполните операцию чтения и пока эта операция чтения не столкнется с фактическим концом файла, состояние " eof " не установлено и feof() возвращает 0.

многие (большинство) стандартные функции ввода-вывода в стандартной библиотеке C уже возвращают некоторый код завершения, который можно использовать для обнаружения условия "конец файла" (например fgetc() возвращение EOF значение). Это означает, что большую часть времени вызова feof() ненужно.

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

причины этой конструкции совершенно логичны. Язык C предназначен для поддержки различных входных потоков и файловых систем, включая 1) файловые системы, которые вообще не хранят размеры файлов, а также 2) файловые системы, которые знают только приблизительный размер файла (например, округленный до ближайшего кластера). В таких файловых системах конец файла обычно обозначается специальным маркером. Вы не знаете, где этот маркер, пока не столкнетесь с ним во время чтения файла. (По той же причине потоки C не гарантируют поддержку позиционирования от SEEK_END происхождения


feof(f) всегда будет возвращать false сразу после открытия файла, потому что if дает вам значение флага, который инициализируется false и устанавливается в true только после сбоя хотя бы одной операции чтения.


можно использовать feof такой:

fgetc(fp);
if (feof(fp))
  ...

feof проверяет набор индикаторов конца файла после чтения, которое попыталось прочитать в конце файла или после него. Это полезно в ситуациях, когда код не контроль чтения из файла, и вы хотите, чтобы остановить обработку после того, как файл был исчерпан.