user2587754
user2587754

Reputation:

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 empty, the statement is not executed. When the file is not empty, the statement is executed.

However, using

if (!feof(ptr))

always executes the statement.

Why does this happen? Is there a way to use the feof function?

Upvotes: 14

Views: 11150

Answers (5)

Keith Thompson
Keith Thompson

Reputation: 263237

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.

Upvotes: 16

s3dev
s3dev

Reputation: 9681

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.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320421

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.

Upvotes: 11

jdarthenay
jdarthenay

Reputation: 3147

feof(f) will always return false right after you open the file because if gives you the value of a flag which is initialized to false and set to true only after at least one reading operation fails.

Upvotes: 7

user4815162342
user4815162342

Reputation: 154911

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.

Upvotes: 3

Related Questions