ferror()

Discussion in 'C Programming' started by Stephen Howe, Dec 10, 2003.

  1. Stephen Howe

    Stephen Howe Guest

    Hi,

    If I attempt to read past the end of a file, feof() will return a non-zero
    value. But can I guarantee that ferror() is 0? In short, will the error
    indicator be set in some implementations just because the end-of-file
    indicator is set? A search on the standard does not reveal if eof is
    regarded as an "error" (if does say something, please quote the heading
    numbers).

    Thanks

    Stephen Howe
    Stephen Howe, Dec 10, 2003
    #1
    1. Advertising

  2. "Stephen Howe" <> wrote:
    >Hi,
    >
    >If I attempt to read past the end of a file, feof() will return a non-zero
    >value. But can I guarantee that ferror() is 0? In short, will the error
    >indicator be set in some implementations just because the end-of-file
    >indicator is set? A search on the standard does not reveal if eof is
    >regarded as an "error" (if does say something, please quote the heading
    >numbers).


    There is not much point in using feof(). Whatever function you
    use to read data will indicate when an end of file or an i/o
    error occurs, for example:

    while (fread(..., fp) != 0) {
    ...
    }

    When the loop exits, you know positively one or the other
    condition has occurred, but generally the the only exception you
    want to take is for an error,

    if (ferror(fp)) {
    ... /* handle the error */
    }

    The program simply continues if no error is indicated, because
    the end of file condition is expected.

    If an error did occur, it makes no difference if feof() is true
    or not.

    --
    Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
    Ukpeagvik (Barrow, Alaska)
    Floyd Davidson, Dec 10, 2003
    #2
    1. Advertising

  3. Stephen Howe

    Dan Pop Guest

    In <3fd7370c$0$9391$> "Stephen Howe" <> writes:

    >If I attempt to read past the end of a file, feof() will return a non-zero
    >value. But can I guarantee that ferror() is 0? In short, will the error
    >indicator be set in some implementations just because the end-of-file
    >indicator is set? A search on the standard does not reveal if eof is
    >regarded as an "error" (if does say something, please quote the heading
    >numbers).


    Having reached the end of file is not considered an error.

    OTOH, I can't figure out the practical side of your question. Why do you
    need any guarantees about the ferror return value once you have reached
    the end of the file?

    In practice, reaching the end of file is the most common reason for the
    failure of an input function. So, if the input function call returns
    a failure indication (EOF or a null pointer), you simply call feof() to
    figure out whether it was an eof condition or an I/O error. You don't
    need to call ferror() at all in this case.

    ferror() is usually useful for output streams, when you don't want to
    bother checking each and every output call. If, before calling fclose(),
    ferror() returns zero, you can assume that everything was fine up to that
    point (if you have performed no actions on that stream that would reset
    the stream's error indicator).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 10, 2003
    #3
  4. Dan Pop wrote:

    (snip regarding feof() and ferror())

    > In practice, reaching the end of file is the most common reason for the
    > failure of an input function. So, if the input function call returns
    > a failure indication (EOF or a null pointer), you simply call feof() to
    > figure out whether it was an eof condition or an I/O error. You don't
    > need to call ferror() at all in this case.


    > ferror() is usually useful for output streams, when you don't want to
    > bother checking each and every output call. If, before calling fclose(),
    > ferror() returns zero, you can assume that everything was fine up to that
    > point (if you have performed no actions on that stream that would reset
    > the stream's error indicator).


    Shouldn't you also check the return value of fclose()?

    I believe that in the case of buffering external to C, all the data
    won't necessarily be pushed all the way to the disk, and a disk full
    condition could still occur.

    I do believe that only a small fraction of programs correctly check
    the return status on output files.

    -- glen
    glen herrmannsfeldt, Dec 10, 2003
    #4
  5. Stephen Howe

    Simon Biber Guest

    "glen herrmannsfeldt" <> wrote:
    > Shouldn't you also check the return value of fclose()?
    >
    > I believe that in the case of buffering external to C, all the
    > data won't necessarily be pushed all the way to the disk, and
    > a disk full condition could still occur.
    >
    > I do believe that only a small fraction of programs correctly
    > check the return status on output files.


    If the fclose function returns an error, which could be due to
    disk full, is it reasonable to ask the user to rectify that
    condition and then retry the fclose?

    ie. something like:
    while(fclose(fp))
    {
    printf("File close failed, press 'r' to retry\n");
    if(getchar() != 'r') break;
    }

    Or is the file pointer invalid after the unsuccessful call?

    --
    Simon.
    Simon Biber, Dec 11, 2003
    #5
  6. Stephen Howe

    Stephen Howe Guest

    > OTOH, I can't figure out the practical side of your question. Why do you
    > need any guarantees about the ferror return value once you have reached
    > the end of the file?


    Colleague's code.

    He has a function which calls various combinations of fread(), fgetc(),
    fgets() and does not bother to inspect the return values.
    At the end, he calls ferror() to see if an error occured reading the file
    and returns a value from the function if it was "successful" or "not". I am
    wondering what happens if the end-of-file is reached whether ferror()
    returns 0 or not. I have to say, it intrinsically does not seem to be
    robust. I would be testing every call to fread(), fgetc(), fgets() in case
    you have an unexpected truncated file.

    > ferror() is usually useful for output streams, when you don't want to
    > bother checking each and every output call. If, before calling fclose(),
    > ferror() returns zero, you can assume that everything was fine up to that
    > point (if you have performed no actions on that stream that would reset
    > the stream's error indicator).


    Is that enough? It could be that disk space is tight, ferror() indicates no
    error yet calling fclose() flushes any buffers in effect and at that point
    the C file system suddenly detects there is a problem. You want to flush
    first and then see what ferror() returns or alternatively take note of what
    fclose() returns.

    Stephen Howe
    Stephen Howe, Dec 11, 2003
    #6
  7. in comp.lang.c i read:
    >Dan Pop wrote:


    >> ferror() is usually useful for output streams, when you don't want to
    >> bother checking each and every output call. If, before calling
    >> fclose(), ferror() returns zero, you can assume that everything was fine
    >> up to that point (if you have performed no actions on that stream that
    >> would reset the stream's error indicator).

    >
    >Shouldn't you also check the return value of fclose()?


    yes, because there may have been buffering of the stream (by default a
    stream referencing a file would be block buffered) and the fclose will
    flush that data before it closes the underlying interface, and either of
    those actions (fflush or underlying_close()) may encounter an error.

    --
    a signature
    those who know me have no need of my name, Dec 11, 2003
    #7
  8. Stephen Howe

    Ben Pfaff Guest

    "Simon Biber" <> writes:

    > If the fclose function returns an error, which could be due to
    > disk full, is it reasonable to ask the user to rectify that
    > condition and then retry the fclose?


    No, you must not do that. See the definition in the Standard:

    7.19.5.1 The fclose function
    Synopsis
    1 #include <stdio.h>
    int fclose(FILE *stream);
    Description

    2 A successful call to the fclose function causes the stream
    pointed to by stream to be flushed and the associated file
    to be closed. Any unwritten buffered data for the stream are
    delivered to the host environment to be written to the file;
    any unread buffered data are discarded. Whether or not the
    ^^^^^^^^^^^^^^^^^^
    call succeeds, the stream is disassociated from the file and
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    any buffer set by the setbuf or setvbuf function is
    disassociated from the stream (and deallocated if it was
    automatically allocated).

    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
    Ben Pfaff, Dec 11, 2003
    #8
  9. Stephen Howe

    Dan Pop Guest

    In <GLLBb.15182$8y1.59614@attbi_s52> glen herrmannsfeldt <> writes:

    >Dan Pop wrote:
    >
    >(snip regarding feof() and ferror())
    >
    >> In practice, reaching the end of file is the most common reason for the
    >> failure of an input function. So, if the input function call returns
    >> a failure indication (EOF or a null pointer), you simply call feof() to
    >> figure out whether it was an eof condition or an I/O error. You don't
    >> need to call ferror() at all in this case.

    >
    >> ferror() is usually useful for output streams, when you don't want to
    >> bother checking each and every output call. If, before calling fclose(),
    >> ferror() returns zero, you can assume that everything was fine up to that
    >> point (if you have performed no actions on that stream that would reset
    >> the stream's error indicator).

    >
    >Shouldn't you also check the return value of fclose()?


    Have I said or implied otherwise?

    Of course you *have* to check it, but this has nothing to do with ferror()
    which can no longer be used after the stream has been closed.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 11, 2003
    #9
  10. Dan Pop wrote:
    (snip)

    >>>ferror() is usually useful for output streams, when you don't want to
    >>>bother checking each and every output call. If, before calling fclose(),
    >>>ferror() returns zero, you can assume that everything was fine up to that
    >>>point (if you have performed no actions on that stream that would reset
    >>>the stream's error indicator).


    >>Shouldn't you also check the return value of fclose()?


    > Have I said or implied otherwise?


    Maybe not, but since you didn't mention it, and since the return value
    of fclose() is so rarely checked, I thought it was worth adding to
    the discussion.

    > Of course you *have* to check it, but this has nothing to do with ferror()
    > which can no longer be used after the stream has been closed.


    -- glen
    glen herrmannsfeldt, Dec 11, 2003
    #10
  11. Stephen Howe

    Alan Balmer Guest

    On Wed, 10 Dec 2003 20:56:06 GMT, glen herrmannsfeldt
    <> wrote:

    >Dan Pop wrote:
    >
    >(snip regarding feof() and ferror())
    >
    >> In practice, reaching the end of file is the most common reason for the
    >> failure of an input function. So, if the input function call returns
    >> a failure indication (EOF or a null pointer), you simply call feof() to
    >> figure out whether it was an eof condition or an I/O error. You don't
    >> need to call ferror() at all in this case.

    >
    >> ferror() is usually useful for output streams, when you don't want to
    >> bother checking each and every output call. If, before calling fclose(),
    >> ferror() returns zero, you can assume that everything was fine up to that
    >> point (if you have performed no actions on that stream that would reset
    >> the stream's error indicator).

    >
    >Shouldn't you also check the return value of fclose()?
    >

    Maybe, but I rarely do. I don't know of any error that would be
    recoverable at that point. If the fwrite's have been checked, about
    the only thing left is inability to flush the buffers. That's better
    detected with an fflush, when you still have ways of correcting the
    problem.

    >I believe that in the case of buffering external to C, all the data
    >won't necessarily be pushed all the way to the disk, and a disk full
    >condition could still occur.
    >
    >I do believe that only a small fraction of programs correctly check
    >the return status on output files.
    >
    >-- glen


    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Dec 11, 2003
    #11
  12. Stephen Howe

    Eric Sosman Guest

    Alan Balmer wrote:
    >
    > On Wed, 10 Dec 2003 20:56:06 GMT, glen herrmannsfeldt
    > <> wrote:
    > >
    > >Shouldn't you also check the return value of fclose()?
    > >

    > Maybe, but I rarely do. I don't know of any error that would be
    > recoverable at that point. If the fwrite's have been checked, about
    > the only thing left is inability to flush the buffers. That's better
    > detected with an fflush, when you still have ways of correcting the
    > problem.


    Even if fflush() succeeds, fclose() can fail.

    Whether the fclose() failure is recoverable or not is only
    part of the story. You may not be able to do anything about
    the error that doomed the fclose(), but you can at least refrain
    from making things worse:

    stream = fopen("datafile.tmp", "w");
    ...
    fclose (stream);
    delete ("datafile.dat");
    rename ("datafile.tmp", "datafile.dat");

    If the fclose() fails (so the integrity of "datafile.tmp" is
    suspect at best), this code merrily clobbers the old and
    presumably valid file with the new and possibly broken one.
    Better, I think, to detect the fclose() failure, leave both
    files intact, and give the user the maximum opportunity to
    sort things out.

    And yes, this has happened. I've told the tale before
    and won't repeat it (go to Google and hunt up the thread
    called "reading an Int Array from a Binary file?" if
    interested). As for me: Once burned, forever shy.

    --
    Eric Sosman, Dec 11, 2003
    #12
  13. Stephen Howe

    Alan Balmer Guest

    On Thu, 11 Dec 2003 15:07:23 -0500, Eric Sosman <>
    wrote:

    >Alan Balmer wrote:
    >>
    >> On Wed, 10 Dec 2003 20:56:06 GMT, glen herrmannsfeldt
    >> <> wrote:
    >> >
    >> >Shouldn't you also check the return value of fclose()?
    >> >

    >> Maybe, but I rarely do. I don't know of any error that would be
    >> recoverable at that point. If the fwrite's have been checked, about
    >> the only thing left is inability to flush the buffers. That's better
    >> detected with an fflush, when you still have ways of correcting the
    >> problem.

    >
    > Even if fflush() succeeds, fclose() can fail.
    >

    I don't doubt it, especially in c.l.c. :) However, I can't think of
    many such failure modes, and those involve catastrophic hardware
    failures. On the implementation I have readily available, any error
    condition which is documented for fclose would also be reported on the
    fopen, and I suspect that's true of many actual implementations (which
    is OT here, of course.)

    > Whether the fclose() failure is recoverable or not is only
    >part of the story. You may not be able to do anything about
    >the error that doomed the fclose(), but you can at least refrain
    >from making things worse:


    The action taken depends on the requirements of the job, the
    implementation, the exact error reported, and probably other things,
    none of which are standardized. I doubt that there is any standard C
    approach to such error recovery which would be very useful.
    >
    > stream = fopen("datafile.tmp", "w");
    > ...
    > fclose (stream);
    > delete ("datafile.dat");
    > rename ("datafile.tmp", "datafile.dat");
    >
    >If the fclose() fails (so the integrity of "datafile.tmp" is
    >suspect at best), this code merrily clobbers the old and
    >presumably valid file with the new and possibly broken one.
    >Better, I think, to detect the fclose() failure, leave both
    >files intact, and give the user the maximum opportunity to
    >sort things out.
    >
    > And yes, this has happened. I've told the tale before
    >and won't repeat it (go to Google and hunt up the thread
    >called "reading an Int Array from a Binary file?" if
    >interested). As for me: Once burned, forever shy.


    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Dec 11, 2003
    #13
  14. Stephen Howe

    Alan Balmer Guest

    On Thu, 11 Dec 2003 16:45:47 -0700, Alan Balmer <>
    wrote:

    > any error
    >condition which is documented for fclose would also be reported on the
    >fopen,


    (Reference post above) Ouch! Didn't catch that bit of nonsense until
    after downloading the post. Should read "any error condition which is
    documented for fclose would also be reported on the fflush, " of
    course.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Dec 12, 2003
    #14
  15. Stephen Howe

    Chris Torek Guest

    >On Thu, 11 Dec 2003 15:07:23 -0500, Eric Sosman <>
    >wrote:
    >> Even if fflush() succeeds, fclose() can fail.


    In article <news:>
    Alan Balmer <> writes:
    >I don't doubt it, especially in c.l.c. :) However, I can't think of
    >many such failure modes, and those involve catastrophic hardware
    >failures.


    It happened in perfectly ordinary "Unixy" code on Sun workstations
    using NFS servers, even with all the hardware working perfectly.

    Files written to the server would be write-behind cached on the
    workstations. On the final fflush()-before-close, the last data
    would be transferred from the user process to the client workstation
    kernel. The kernel continued to cache the data, not sending any
    of it to the NFS server yet.

    On the close(), the workstation would realize that it was now
    time to send the cached data to the server, which would reject
    the write with EDQUOT, "user is over quota".

    The close() would return the EDQUOT error to the user process,
    alerting the user that his file was incomplete because he was
    now out of administrator-assigned disk space.

    (This kind of failure generally came as a total shock to the users,
    whose programs completely ignored the close() failure and often
    followed the failed close() by a rename() operation that wiped
    out the original backup file. Now they had plenty of disk space
    for the data, but no data to go in it.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Dec 12, 2003
    #15
  16. Stephen Howe

    Dan Pop Guest

    In <ma3Cb.364935$ao4.1227051@attbi_s51> glen herrmannsfeldt <> writes:

    >Dan Pop wrote:
    >(snip)
    >
    >>>>ferror() is usually useful for output streams, when you don't want to
    >>>>bother checking each and every output call. If, before calling fclose(),
    >>>>ferror() returns zero, you can assume that everything was fine up to that
    >>>>point (if you have performed no actions on that stream that would reset
    >>>>the stream's error indicator).

    >
    >>>Shouldn't you also check the return value of fclose()?

    >
    >> Have I said or implied otherwise?

    >
    >Maybe not, but since you didn't mention it, and since the return value
    >of fclose() is so rarely checked, ^^^^^^^^^^^^^^^^

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    How do you know?

    >I thought it was worth adding to the discussion.


    Huh? Has it anything whatsoever to do with ferror, which is the topic
    of this discussion?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 12, 2003
    #16
  17. Stephen Howe

    Stephen Howe Guest

    Right. In general, pay attention to the return value of fclose()
    particularly if the file is opened for writing.

    Stephen Howe
    Stephen Howe, Dec 12, 2003
    #17
  18. Stephen Howe

    Dan Pop Guest

    In <> Alan Balmer <> writes:

    >On Wed, 10 Dec 2003 20:56:06 GMT, glen herrmannsfeldt
    ><> wrote:
    >
    >>Dan Pop wrote:
    >>
    >>(snip regarding feof() and ferror())
    >>
    >>> In practice, reaching the end of file is the most common reason for the
    >>> failure of an input function. So, if the input function call returns
    >>> a failure indication (EOF or a null pointer), you simply call feof() to
    >>> figure out whether it was an eof condition or an I/O error. You don't
    >>> need to call ferror() at all in this case.

    >>
    >>> ferror() is usually useful for output streams, when you don't want to
    >>> bother checking each and every output call. If, before calling fclose(),
    >>> ferror() returns zero, you can assume that everything was fine up to that
    >>> point (if you have performed no actions on that stream that would reset
    >>> the stream's error indicator).

    >>
    >>Shouldn't you also check the return value of fclose()?
    >>

    >Maybe, but I rarely do. I don't know of any error that would be
    >recoverable at that point. If the fwrite's have been checked, about
    >the only thing left is inability to flush the buffers. That's better
    >detected with an fflush,


    All fflush can tell you is that the data has successfully left the
    stdio buffers. It may still be bufferred by the OS. Only fclose can
    confirm that it successfully reached its final destination.

    >when you still have ways of correcting the problem.


    Even if it's not recoverable, the user still needs to be informed about
    the problem. As it is impossible to predict the consequences of a
    failed fclose, it is unacceptable to ignore this possibility.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 12, 2003
    #18
  19. Stephen Howe

    Dan Pop Guest

    In <> Alan Balmer <> writes:

    >On Thu, 11 Dec 2003 16:45:47 -0700, Alan Balmer <>
    >wrote:
    >
    >> any error
    >>condition which is documented for fclose would also be reported on the
    >>fopen,

    >
    >(Reference post above) Ouch! Didn't catch that bit of nonsense until
    >after downloading the post. Should read "any error condition which is
    >documented for fclose would also be reported on the fflush, " of
    >course.


    Chapter and verse, please.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 12, 2003
    #19
  20. Stephen Howe

    Dan Pop Guest

    In <3fd9c2f0$0$13343$> "Stephen Howe" <> writes:

    >Right. In general, pay attention to the return value of fclose()
    >particularly if the file is opened for writing.


    If it's opened for input only, you couldn't/shouldn't care less.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Dec 12, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rCs

    EOF vs. feof() and ferror()

    rCs, Oct 31, 2006, in forum: C Programming
    Replies:
    8
    Views:
    1,744
    Barry Schwarz
    Nov 1, 2006
  2. Spiros Bousbouras

    Is this a correct way to use ferror() ?

    Spiros Bousbouras, Nov 19, 2007, in forum: C Programming
    Replies:
    1
    Views:
    387
    santosh
    Nov 19, 2007
  3. , India

    question on ferror() function

    , India, Aug 11, 2008, in forum: C Programming
    Replies:
    4
    Views:
    693
    Ian Collins
    Aug 12, 2008
Loading...

Share This Page