James Ko James Ko - 1 year ago 43
C Question

Is it correct to check if the number of items read is less than requested, rather than 0, in fread(3)?

I'm a beginner to C. I was wondering if it correct to check if the return value of

(which is the number of items read) is less than the number requested, rather than just 0, to detect EOF. For example, say you have

#include <stdio.h>

int main(void)
unsigned char buffer[1024];

while (fread(buffer, 1, sizeof(buffer), stdin) == sizeof(buffer))
printf("%s\n", "Not EOF yet");

printf("%s\n", "At EOF");

return 0;

Is this correct? Should the check for
== sizeof(buffer)
!= 0
instead? Is
allowed to partially fill the buffer?

The reason I ask: It appears that
may return less than
. Quoting the manpage:

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of
bytes requested;
this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a ter-
minal), or because read() was interrupted by a signal.

However the same logic does not seem to apply to
for some reason:

On success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1. If an error occurs, or the end of the file is
reached, the return value is a short item count (or zero).

So I would like confirmation that the check should indeed be
== sizeof(buffer)
and not
!= 0

Thanks for helping!

usr usr
Answer Source

The part of the manual you qouted says:

If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).

That means you can't use !=0 to check if no error has occurred as fread() could return a short item count.

The man page of fread() also states:

fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.

So if the items count returned is less than requested, then you have to use feof() or ferror() to figure out which one occurred (If it's end-of-file then you can conclude that it's not an input error but the end of input on whatever stream you are reading from).