简体   繁体   English

混淆 == EOF 与 feof

[英]Confusion with == EOF vs feof

I opened a file, the stream is found at the address of pointer ptr .我打开了一个文件,在指针ptr的地址找到了流。 I am attempting to see whether or not a file is blank.我正在尝试查看文件是否为空白。 Using the following使用以下

if (fgetc(ptr) != EOF)

works as expected.按预期工作。 When the file is blank, the statement is not executed.当文件为空时,不执行语句。 When the file is not blank, the statement is not executed.当文件不为空时,不执行语句。

However, using但是,使用

if (!feof(ptr))

always executes the statement.总是执行语句。

Why does this happen?为什么会这样? Is there a way to use the feof function?有没有办法使用feof函数?

Is there a way to use the feof function?有没有办法使用feof函数?

Yes, there is.就在这里。 After an input function has returned a value that indicates that it has no more input to process, you can call feof() and/or ferror() to determine whether the condition was caused by reaching the end of the input or some error condition.输入函数返回一个表明它没有更多输入要处理的值后,您可以调用feof()和/或ferror()来确定该条件是由到达输入末尾还是某些错误条件引起的。

This is the only valid use for the feof() and ferror() functions.这是feof()ferror()函数的唯一有效用途。

The result that indicates that no more input remains differs from one function to another.表明不再有输入的结果因一个函数而异。 For example fgetc() returns the value EOF , fgets() returns a null pointer, and fread() returns some value less than the number of records requested.例如fgetc()返回值EOFfgets()返回一个空指针, fread()返回一个小于请求记录数的值。 You need to read the documentation for each input function to see how it works.您需要阅读每个输入函数的文档以了解它是如何工作的。

In C standard library "end of file" is not an independent self-detecting condition.在 C 标准库中,“文件结尾”不是独立的自检测条件。 "End of file" is merely a file state set by the preceding read operation . “文件结束”只是前面读取操作设置的文件状态。 Until you perform a read operation and until that read operation bumps into the actual end of file, "eof" state is not set and feof() returns 0.直到您执行读取操作并且直到读取操作碰到文件的实际末尾,“eof”状态才被设置并且feof()返回 0。

Many (most) standard I/O functions in C standard library already return some completion code that can be used to detect "end of file" condition (like fgetc() returning EOF value). C 标准库中的许多(大多数)标准 I/O 函数已经返回了一些可用于检测“文件结束”条件的完成代码(如fgetc()返回EOF值)。 This means that most of the time calling feof() is unnecessary.这意味着大多数时候调用feof()是不必要的。

In other words, if you think about "end of file" as a brick wall, in C standard library it is not sufficient to stand right in front of that wall in order to detect it.换句话说,如果您将“文件结尾”视为一堵砖墙,那么在 C 标准库中,仅仅站在那堵墙的正前方检测它是不够的。 It is necessary to actually bump into that wall with your forehead in order to discover its presence.为了发现它的存在,有必要用你的前额实际撞到那堵墙。

When you open an empty file, you begin in a state "right before the wall".当您打开一个空文件时,您会从“墙前”的状态开始。 At this point "end of file" condition is not detected yet.此时尚未检测到“文件结束”条件。 You have to try reading something in order to crash into that wall and thus detect its presence.你必须尝试阅读一些东西才能撞到那堵墙上,从而检测到它的存在。

The reasons for this design are perfectly logical.这种设计的原因是完全合乎逻辑的。 C language is designed to support various input streams and file systems, including 1) file systems that do not store file sizes at all, as well as 2) file systems that know only approximate file size (like rounded to a nearest cluster). C 语言旨在支持各种输入流和文件系统,包括 1) 根本不存储文件大小的文件系统,以及 2) 只知道近似文件大小的文件系统(如四舍五入到最近的集群)。 In such file systems the end of file is usually designated by a special marker.在此类文件系统中,文件的结尾通常由特殊标记指定。 You don't know where that marker is until you run into it while reading the file.在读取文件时遇到该标记之前,您不知道该标记在哪里。 (For the very same reason C streams do not guarantee support for positioning from SEEK_END origin in fseek function.) (出于同样的原因,C 流不保证在fseek函数中支持从SEEK_END原点定位。)

As @Barmar noted in the comments, an even better example of an input stream without a pre-determined "end of file" position is standard input linked to terminal.正如@Barmar 在评论中指出的那样,没有预先确定的“文件结尾”位置的输入流的更好示例是链接到终端的标准输入。

feof(f)在您打开文件后将始终返回false ,因为 if 为您提供了一个标志的值,该标志初始化为 false 并仅在至少一个读取操作失败后才设置为 true。

You could use feof like this:你可以像这样使用feof

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

feof checks an end-of-file indicator set after a read that attempted to read at or past the end of file. feof在尝试读取文件末尾或文件末尾之后检查文件末尾指示符集。 It is useful in situations where code that you don't control was reading from the file, and you want to stop the processing once the file has been exhausted.它在您无法控制的代码正在从文件中读取的情况下很有用,并且您希望在文件耗尽后停止处理。

Late answer, however to add a helpful quote from Programming in C (4th Edition) by Stephen Kochan, p.迟到的答案,但是添加一个有用的引用来自 Stephen Kochan 的Programming in C (4th Edition),p。 367: 367:

Remember, feof() tells you that an attempt has been made to read past the end of a file, which is not the same as telling you that you just read the last data item from a file.请记住, feof()告诉您已尝试读取文件末尾之后的内容,这告诉您刚刚从文件中读取最后一个数据项不同。 You have to read one past the last data item for feof() to return nonzero.您必须读取feof()的最后一个数据项才能返回非零值。

Italics mine.斜体我的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM