how to detect read/write errors when using fread() and fwrite?

In c i am trying to read/write to a file with fread/fwrite().

According to this answer i can use ferror() and feof() to check for errors.

My question is, how can i use them to do this? also what use does feof() provide? why would one want to check if a file has hit EOF in the first place (apart from when reading)?

>Solution :

The basic recipe is

size_t r = fread(buf, m, n, fp);
if(r > 0)
    success;
else if(ferror(fp))
    handle error condition;
else
    handle EOF condition;

Basically, in this case, a 0 return means "either EOF or error", and you have to do something else to figure out which. The "something else" is that feof(fp) is true if there was an EOF, and ferror(fp) is true if there was an error. (Whether it’s possible to have both an EOF and error condition at the same time is an interesting question which I am not going to try to answer.)

But, it’s true, having both feof() and ferror() available is, mildly, overkill. Typically you only need one or the other. In the code fragment above I used ferror but not feof. Obviously I could have arranged it a different way:

if(r > 0)
    success;
else if(feof(fp))
    handle EOF condition;
else
    handle error condition;

I believe it would also be safe to write it as

if(feof(fp))
     handle EOF condition;
else if(ferror(fp))
     handle error condition;
else success;

That is, in this respect, feof and ferror are different than the errno variable. With just one or two exceptions, errno is valid only if a function has just returned an error condition. With errno, you have to first check a function’s return value to see if there was an error, and then, only if there was, inspect errno to figure out what kind of error it was. But, if you want to, theoretically you can use feof and/or ferror as your primary success/fail discriminator: if both feof(fp) and feror(fp) return false, you can infer that the call must have succeeded.

Leave a Reply