Given the following C code:
int eofCount = 0;
while (true) {
int c = fgetc(stdin);
if (c == EOF) eofCount++;
}
Will eofCount ever become greater than 1?
I can't find anything in C docs describing what happens with fgetc after EOF has been reached once. I know I can do this book-keeping myself, but if the stdlib does it for me that'd be great.
I'm not looking for code snippets because I've already try this with glibc and in fact eofCount is incremented past EOF. I would like stdlib source code reference or spec that confirms this is the defined behavior. Relying on undefined behavior could lead to problems down the road.
As long as you're not reading from an interactive Linux terminal (i.e. you do not open a file or pipe stdin from some other file/process), once you read EOF all future reads will also read EOF.
If you are reading from a Linux terminal, pressing the key sequence for EOF (CTRL-D on Linux) will read as EOF but you can still enter in more characters and read them.
From section 7.21.7.1 of the C standard:
3 If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the
fgetc
function returnsEOF
. Otherwise, thefgetc
function returns the next character from the input stream pointed to by stream. If a read error occurs, the error indicator for the stream is set and thefgetc
function returnsEOF
.
Does fgetc return EOF on every call after end-of-file reached?
It depends of 2 indicators and I/O function calls.
Although not mentioned by OP, there are 2 reasons why fgetc(stdin);
returns EOF
and how they affect following fgetc()
calls is not symmetric. Further, use of various I/O functions affect 2 indicators that in turn affect following fgetc()
calls
End-of-file.
Input error.
The C spec is explicit on the end-of-file indicator causing subsequent EOF
.
If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character ... C11 §7.21.7.1 2
When end-of-file occurs or had occurred, a persistent flag is set: end-of-file indicator, so subsequent calls to fgetc()
will return EOF
.
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the
fgetc
function returnsEOF
... §7.21.7.1 3
When a rare input error occurs, fgetc()
returns EOF
, but that event does not set the end-of-file indicator, but an error indicator is set. Subsequent calls do not necessarily return EOF
, even though a error indicator is set. IMO, the C spec is insufficiency clear on this point.
If a read error occurs, the error indicator for the stream is set and the
fgetc
function returnsEOF
§7.21.7.1 3
A call to feof()
, and ferror()
can be used to distinguish what caused the EOF
, yet also may reflect prior I/O activity. Thus good code promptly checks these functions after an EOF
is returned and clears them if following I/O is to occur.
The end-of-file indicator and error indicator can be cleared with void clearerr(FILE *stream);
The rewind()
function clears the error indicator.
ungetc()
will clear the end-of-file indicator.
Other I/O functions also affect these indicators.
Subsequent calls to fgetc()
might not return EOF
if the condition the caused the first EOF
is removed and corresponding indicator is cleared.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With