In various examples found on the web fgetc()
is used like this:
FILE *fp = fopen(PATH, "r");
if (fp == NULL) {
perror("main");
exit(EXIT_FAILURE);
}
int ch;
while (ch = fgetc(fp) != EOF) {
// do something
}
But according to the manpage to fgetc()
If a read error occurs, the error indicator for the stream shall be set, fgetc() shall return EOF, [CX] and shall set errno to indicate the error.
So need I check this too? And how?
You can check it with ferror(3), right after the while:
ferror returns a non-zero if an error occured.
If you want use fp after an error occured, you'll need to clear the error flag with clearerr:
This is what the specs say:
As long as you store the return value in an
int
and not achar
, it is sufficient to check forEOF
because it is guaranteed not to represent a valid character value.Also, in your code, this:
should be:
The additional parentheses are required because
!=
has higher precedence than=
.Looping until
fgetc
returnsEOF
is perfectly fine. Afterwards, if you want to know whether the loop ended due to simply reaching the end of the file or due to an error, you should callferror
orfeof
. If you don't care you can skip the call.Note that it matters whether you check
feof
orferror
, because the error indicator for a stream is sticky and can evaluate true even when hitting eof was the cause offgetc
failure. Normally you should usefeof
to check, and if it returns false, conclude that the loop stopped due to a new error.