#c #file
Вопрос:
для потока ФАЙЛА*, если я прочитаю как можно больше данных, feof(поток) вернет мне ненулевое значение. Затем, если я закрою поток, он(поток) будет продолжать возвращать мне ненулевое значение? Это ГАРАНТИРОВАНО?
Ответ №1:
Вызов feof() в закрытом файле бессмыслен (на самом деле хуже, чем бессмыслен — он не определен, поэтому может произойти все, что угодно).
Из стандарта C:
Значение указателя на файловый объект не определено после закрытия связанного файла (включая стандартные текстовые потоки).
и
Успешный вызов функции fclose приводит к сбросу потока, на который указывает поток, и закрытию связанного файла. Любые неписаные буферизованные данные для потока доставляются в среду хоста для записи в файл; любые непрочитанные буферизованные данные удаляются. Независимо от того, выполняется вызов или нет, поток отсоединяется от файла, и любой буфер, установленный функцией setbuf или setvbuf, отсоединяется от потока (и освобождается, если он был выделен автоматически).
Ответ №2:
В зависимости от реализации библиотеки вызов fclose() приведет к освобождению ресурсов в файловой структуре, и последующие попытки вполне могут привести к сбою. Я считаю, что стандартным термином для этого является «неопределенное поведение».
Ответ №3:
Не делай этого. Не пытайтесь работать feof()
с закрытым файлом. Результат не определен. Следите за тем, какие дескрипторы файлов закрыты каким-либо другим способом, вместо того, чтобы предполагать, что на них будет отображаться EOF.
В общем, неопределенного поведения в C следует избегать при написании переносимого кода… он может сделать что-то разумное на вашей платформе, но может сделать что-то совершенно нелепое или неожиданное на другой.
Люди из группы Usenet comp.lang.c
много лет назад придумали гипотетический компьютер DeathStation 9000, который демонстрирует самое пугающе плохое поведение в случае неопределенных конструкций. Это своего рода обучающий инструмент, чтобы отпугнуть вас от того, чтобы полагаться на неопределенное поведение в C 🙂
Ответ №4:
Не для каждой реализации feof().
На самом деле, вы даже не можете гарантировать, что любой вызов f* будет работать после того, как вы позвоните в fclose.