views:

359

answers:

3

If a call to fread() returns 0 and ferror() indicates an error (vs. EOF), is it OK to retry the read or is it better to close and reopen the file?

I can't start over entirely -- the input file has been partially processed in a way that can't be undone (say I'm writing out a chunk at a time to a socket and, due to existing protocol, have no way of telling the remote end, "never mind, I need to start over").

I could fclose() and fopen() the file, fseek() past the data already processed, and continue the fread()-ing from there, but is all that necessary?

+6  A: 

There's no "one size fits all" solution, since different errors can require different handling. Errors from fread() are unusual; if you're calling it correctly, an error may indicate a situation that has left the FILE* in a weird error state. In that case you're best off calling fclose(), fopen(), fseek() to get things back in a good state.

If you're coding for something that's happening, please mention the actual errors you're getting from ferror()...

dwc
How can I tell what kind of error happened with fread()? I don't think errno gets set (at least not according to the C standard).fread() is being called correctly, the problem is with the underlying filesystem.
Dan
ferror() returns non-zero on error. Use that result to check for specific errors or hand off to perror()/strerror to see what you're getting.
dwc
+6  A: 

You can give the clearerr function a look.

dirkgently
Good point. If I want to retry the fread() without closing/opening the file I'll need to clearerr() first.
Dan
FWIW, if you want to read a stream after an error you need to clear the error using clearerr. This behavior is defined by the standard as a portable thing to do.
dirkgently
+1, wish I'd thought of it first ;)
dwc
A: 

You can show the error to the user with perror() or strerror() and ask her is she wants to retry.

It's not mandatory for the implementation to provide such an error message, though. You should set errno to 0 before calling fread(); if it fails and errno is still 0 then no error information will be available.

Bastien Léonard