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

1

2

I'm a beginner to C. I was wondering if it correct to check if the return value of fread(3) (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) be != 0 instead? Is fread allowed to partially fill the buffer?

The reason I ask: It appears that read may return less than sizeof(buffer). 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 fread 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!

Spalla answered 4/9, 2016 at 22:45 Comment(1)
What you have is correct. Though when the condition is false it does not necessarily mean you have reached the end of file: "fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred. ".Thaxton
F
3

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).

Freighter answered 4/9, 2016 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.