Here is how end-of-file works in C. The input channels are called input streams; disk files and stdin
are both input streams. The "end-of-file" state is a flag that a stream has, and that flag is triggered when you try to read from a stream, but it turns out there are no more characters in the stream, and there never will be any more. (If the stream is still active but just waiting for user input for example, it is not considered to be end-of-file; read operations will block).
Streams can have other error states, so looping until "end-of-file" is set is usually wrong. If the stream does go into an error state then your loop will never exit (aka. "infinite loop").
The end-of-file state can be checked by feof
. However, some input operations also can signal an error as well as, or instead of, returning the actual data they were intended to read. These functions can return the value EOF
. Usually these functions return EOF
in both cases: end-of-file, and stream error. This is different to feof
which only returns true
in the case of end-of-file.
For example, getchar()
and scanf
will return EOF
if it was end-of-file, but also if the stream is in an error state.
So it is OK to use getchar()
's result as a loop condition, but not feof
on its own.
Also, it is sometimes not OK to use scanf() != EOF
as a loop condition. It's possible that there is no stream error, but just that the data you requested wasn't there. For example, if you scan for "%d"
but there are letters in the stream. Instead, it's better to check for successful conversion (scanf returns the number of successful conversions it performed). Then when you exit your loop, you can go on to call feof
and ferror
to see whether it was due to end-of-file, or error, or just unexpected input.