简体   繁体   中英

Confusion with == EOF vs feof

I opened a file, the stream is found at the address of pointer 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?

Is there a way to use the feof function?

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.

This is the only valid use for the feof() and ferror() functions.

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. 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. "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.

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). This means that most of the time calling feof() is unnecessary.

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. 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). 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.)

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.

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

You could use feof like this:

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. 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. 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. You have to read one past the last data item for feof() to return nonzero.

Italics mine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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