我打开了一个文件,在指针
ptr
的地址找到了流。我正在尝试查看文件是否为空。使用以下
if (fgetc(ptr) != EOF)
按预期工作。当文件为空时,不执行该语句。当文件不为空时,执行该语句。
但是,使用
if (!feof(ptr))
始终执行该语句。
为什么会出现这种情况?有没有办法使用
feof
功能?
有没有办法使用
功能?feof
是的,有。 After 输入函数返回一个值,表明它没有更多的输入需要处理,您可以调用
feof()
和/或 ferror()
来确定该情况是否是由于到达输入末尾或某些错误引起的状况。
这是
feof()
和 ferror()
函数的唯一有效用途。
表明不再有输入的结果因函数而异。例如,
fgetc()
返回值EOF
,fgets()
返回空指针,fread()
返回小于所请求记录数的某个值。您需要阅读每个输入函数的文档才能了解其工作原理。
在C标准库中“文件结束”不是一个独立的自检测条件。 “文件结束”仅仅是由前面的读取操作设置的文件状态。在执行读取操作并且读取操作到达实际文件末尾之前,不会设置“eof”状态并且 feof()
返回 0。
C 标准库中的许多(大多数)标准 I/O 函数已经返回一些可用于检测“文件结束”条件的完成代码(例如
fgetc()
返回
EOF
值)。这意味着大多数时候调用 feof()
是不必要的。 换句话说,如果您将“文件结尾”视为一堵砖墙,那么在 C 标准库中,仅仅站在该墙前面来检测它是不够的。有必要用你的额头实际撞到那堵墙才能发现它的存在。
当您打开一个空文件时,您会处于“就在墙前”的状态。此时尚未检测到“文件结束”条件。你必须尝试阅读一些内容才能撞到那堵墙,从而检测到它的存在。
这种设计的原因是完全合乎逻辑的。 C 语言旨在支持各种输入流和文件系统,包括 1)根本不存储文件大小的文件系统,以及 2)仅知道近似文件大小(例如四舍五入到最近的簇)的文件系统。在此类文件系统中,文件结尾通常由特殊标记指定。您不知道该标记在哪里,直到您在阅读文件时遇到它。 (出于同样的原因,C 流不保证支持在
SEEK_END
函数中从
fseek
原点定位。)正如 @Barmar 在评论中指出的,没有预先确定的“文件结尾”位置的输入流的一个更好的例子是链接到终端的标准输入。
feof(f)
在打开文件后总是会立即返回
false
,因为 if 会为您提供一个标志的值,该标志被初始化为 false,并且仅在至少一次读取操作失败后才设置为 true。feof
:
fgetc(fp);
if (feof(fp))
...
feof
在尝试读取文件末尾或超过文件末尾的读取后检查设置的文件结束指示符。当您
不控制的代码正在从文件中读取,并且您希望在文件耗尽后停止处理时,它非常有用。
请记住,
feof()
告诉您已尝试读取过去 文件的末尾,这与告诉您您只是 从文件中读取最后一个数据项。您必须读取最后一个数据项
才能返回feof()
非零。 斜体是我的。