feof usage

Discussion in 'C Programming' started by Mantorok Redgormor, Sep 20, 2003.

  1. My professor that teaches C says that using feof to test if EOF is
    reached while using a function like fgets on a file is okay. but i've
    been told elsewhere that it is not okay. what is the case here? is it
    okay or not?




    nethlek
    Mantorok Redgormor, Sep 20, 2003
    #1
    1. Advertising

  2. Mantorok Redgormor

    Artie Gold Guest

    Mantorok Redgormor wrote:
    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?
    >

    It's OK -- but feof() only returns a non-zero (`true') value *after*
    an attempted `read' has failed.

    HTH,
    --ag
    --
    Artie Gold -- Austin, Texas
    Artie Gold, Sep 20, 2003
    #2
    1. Advertising

  3. Mantorok Redgormor

    Mac Guest

    On Fri, 19 Sep 2003 19:11:20 +0000, Mantorok Redgormor wrote:

    >
    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?
    >


    The issue is that feof() only tells you AFTER you have attempted to read
    past the end of the file. If you understand that, and code accordingly, it
    is OK to use it, AFAIK.

    That is, if a file has n characters, you can read all of them with fgets
    and feof() will still return zero (false). But if you try to read n+1,
    then fgets will still succeed, but feof() will return non-zero (true).

    HTH

    Mac
    --
    Mac, Sep 20, 2003
    #3
  4. Mantorok Redgormor

    Jack Klein Guest

    On 19 Sep 2003 19:11:20 -0700, (Mantorok Redgormor)
    wrote in comp.lang.c:

    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?


    This is covered in the FAQ, specifically at
    http://www.eskimo.com/~scs/C-faq/q12.2.html

    Generally it is not a good idea to use feof() this way. It is not so
    bad if you test for EOF after an input operation and before trying to
    use the input data. But it can still cause problems, because an error
    does not cause feof() to return a non-zero value.

    There are all kinds of things that can cause an error in a file
    operation. Hard drives are pretty reliable these days, but they are
    still wear parts. Or a user could remove the media containing a file,
    such as a floppy disk or CD. Or the network connection could go down.

    All functions that can read from a file return a value that indicates
    whether they succeeded or failed. fgets() returns the pointer you
    passed it if it succeeded, or a null pointer if it failed. So to use
    fgets() in a loop:

    while (NULL != fgets(buffer, sizeof buffer, file_ptr))
    {
    /* ... */
    }

    After your input function indicates a failure, you can use feof() and
    ferror() to determine whether you successfully read the entire file or
    whether an error occurred.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Sep 20, 2003
    #4
  5. Mantorok Redgormor wrote:
    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?


    Sure, it's OK. But it is useless until EOF has already been reached, by
    which time whatever you are using to read the file (fgets, fgetc, fread,
    even fscanf) has already given an error indication. feof can be used to
    sort out what kind of input error it was. You don't reach EOF on a read
    that completely succeeds, so feof is useless then.


    --
    Martin Ambuhl
    Martin Ambuhl, Sep 20, 2003
    #5
  6. "Mantorok Redgormor" <> wrote in message
    news:...
    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?


    Most users of feof() have previously used Pascal, where it is required to
    use feof() before reading to avoid a fatal error.

    C requires an attempt to read past the end of file before feof() will
    indicate it, so direct translation of Pascal feof() to C's feof() tend to
    fail.

    All C input functions signal the failure to do what they were asked to do,
    and that tends to be a better way to do the test.

    -- glen
    Glen Herrmannsfeldt, Sep 20, 2003
    #6
  7. Mantorok Redgormor

    Mac Guest

    On Sat, 20 Sep 2003 04:16:09 +0000, Martin Ambuhl wrote:

    > Mantorok Redgormor wrote:
    >> My professor that teaches C says that using feof to test if EOF is
    >> reached while using a function like fgets on a file is okay. but i've
    >> been told elsewhere that it is not okay. what is the case here? is it
    >> okay or not?

    >
    > Sure, it's OK. But it is useless until EOF has already been reached, by
    > which time whatever you are using to read the file (fgets, fgetc, fread,
    > even fscanf) has already given an error indication. feof can be used to
    > sort out what kind of input error it was. You don't reach EOF on a read
    > that completely succeeds, so feof is useless then.


    Actually, fgets doesn't provide error notification on reaching the end of
    a file unless it wasn't able to read any characters, in which case it
    returns NULL. It also returns NULL if there is an error reading from the
    file.

    Apart from that I agree with you. It seems that feof() is seldom useful,
    except to distinguish between end of file and some other file error after
    the fact.

    Mac
    --
    Mac, Sep 20, 2003
    #7
  8. Mantorok Redgormor

    LibraryUser Guest

    Mac wrote:
    > On Fri, 19 Sep 2003 19:11:20 +0000, Mantorok Redgormor wrote:
    >
    > > My professor that teaches C says that using feof to test if EOF
    > > is reached while using a function like fgets on a file is okay.
    > > but i've been told elsewhere that it is not okay. what is the
    > > case here? is it okay or not?

    >
    > The issue is that feof() only tells you AFTER you have attempted
    > to read past the end of the file. If you understand that, and
    > code accordingly, it is OK to use it, AFAIK.
    >
    > That is, if a file has n characters, you can read all of them with
    > fgets and feof() will still return zero (false). But if you try to
    > read n+1, then fgets will still succeed, but feof() will return
    > non-zero (true).


    Correction - that final fgets call will not succeed, it will
    return NULL. This may describe either the end-of-file, or a read
    error. feof() allows you to disambiguate them.

    --
    Replies should be to the newsgroup
    Chuck Falconer, on vacation.
    LibraryUser, Sep 20, 2003
    #8
  9. Mantorok Redgormor

    LibraryUser Guest

    Glen Herrmannsfeldt wrote:
    > "Mantorok Redgormor" <> wrote in message
    >
    > > My professor that teaches C says that using feof to test if EOF
    > > is reached while using a function like fgets on a file is okay.
    > > but i've been told elsewhere that it is not okay. what is the
    > > case here? is it okay or not?

    >
    > Most users of feof() have previously used Pascal, where it is
    > required to use feof() before reading to avoid a fatal error.
    >
    > C requires an attempt to read past the end of file before feof()
    > will indicate it, so direct translation of Pascal feof() to C's
    > feof() tend to fail.
    >
    > All C input functions signal the failure to do what they were
    > asked to do, and that tends to be a better way to do the test.


    The reason for the difference is that Pascal input is always
    buffered, so that a look ahead can be implemented by examining
    f^. In C, such lookahead involves the use of ungetc() and the
    user needs to be highly aware of what is going on. In Pascal
    OTOH use of the buffering can cause problems with interactive
    input, leading to so-called lazy-io schemes, which in turn
    require the user to be aware when using eof and eoln calls.

    Neither scheme is perfect, but the trade-offs are different.

    --
    Replies should be to the newsgroup
    Chuck Falconer, on vacation.
    LibraryUser, Sep 20, 2003
    #9
  10. "LibraryUser" <> wrote in message
    news:...
    > Glen Herrmannsfeldt wrote:
    > > "Mantorok Redgormor" <> wrote in message
    > >
    > > > My professor that teaches C says that using feof to test if EOF
    > > > is reached while using a function like fgets on a file is okay.
    > > > but i've been told elsewhere that it is not okay. what is the
    > > > case here? is it okay or not?

    > >
    > > Most users of feof() have previously used Pascal, where it is
    > > required to use feof() before reading to avoid a fatal error.
    > >
    > > C requires an attempt to read past the end of file before feof()
    > > will indicate it, so direct translation of Pascal feof() to C's
    > > feof() tend to fail.
    > >
    > > All C input functions signal the failure to do what they were
    > > asked to do, and that tends to be a better way to do the test.

    >
    > The reason for the difference is that Pascal input is always
    > buffered, so that a look ahead can be implemented by examining
    > f^. In C, such lookahead involves the use of ungetc() and the
    > user needs to be highly aware of what is going on. In Pascal
    > OTOH use of the buffering can cause problems with interactive
    > input, leading to so-called lazy-io schemes, which in turn
    > require the user to be aware when using eof and eoln calls.


    Interactive input can be confusing in C, too.

    > Neither scheme is perfect, but the trade-offs are different.


    Using the assumptions of one language in programming the other tends to show
    those trade-offs.

    -- glen
    Glen Herrmannsfeldt, Sep 20, 2003
    #10
  11. Mantorok Redgormor

    Mac Guest

    On Sat, 20 Sep 2003 07:43:54 +0000, LibraryUser wrote:

    > Mac wrote:
    >> On Fri, 19 Sep 2003 19:11:20 +0000, Mantorok Redgormor wrote:
    >>
    >> > My professor that teaches C says that using feof to test if EOF
    >> > is reached while using a function like fgets on a file is okay.
    >> > but i've been told elsewhere that it is not okay. what is the
    >> > case here? is it okay or not?

    >>
    >> The issue is that feof() only tells you AFTER you have attempted
    >> to read past the end of the file. If you understand that, and
    >> code accordingly, it is OK to use it, AFAIK.
    >>
    >> That is, if a file has n characters, you can read all of them with
    >> fgets and feof() will still return zero (false). But if you try to
    >> read n+1, then fgets will still succeed, but feof() will return
    >> non-zero (true).

    >
    > Correction - that final fgets call will not succeed, it will
    > return NULL. This may describe either the end-of-file, or a read
    > error. feof() allows you to disambiguate them.
    >


    I may not have expressed myself as clearly as I could have. The bottom
    line, though, is that fgets will not return NULL if it reads a few
    characters and THEN encounters eof. It will return NULL when it encounters
    the end of the file without reading any characters into the buffer. Unless
    I am reading the standard wrong, which is certainly possible.

    Mac
    --
    Mac, Sep 21, 2003
    #11
  12. In 'comp.lang.c', (Mantorok Redgormor) wrote:

    > My professor that teaches C says that using feof to test if EOF is
    > reached while using a function like fgets on a file is okay. but i've
    > been told elsewhere that it is not okay. what is the case here? is it
    > okay or not?


    It's not. Your professor needs to reread its C-book and the C-FAQ too:

    http://www.eskimo.com/~scs/C-faq/q12.2.html

    --
    -ed- [remove YOURBRA before answering me]
    The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    <blank line>
    FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
    Emmanuel Delahaye, Sep 21, 2003
    #12
  13. Mantorok Redgormor

    LibraryUser Guest

    Mac wrote:
    > On Sat, 20 Sep 2003 07:43:54 +0000, LibraryUser wrote:
    > > Mac wrote:
    > >> On Fri, 19 Sep 2003 19:11:20 +0000, Mantorok Redgormor wrote:
    > >>
    > >> > My professor that teaches C says that using feof to test if
    > >> > EOF is reached while using a function like fgets on a file
    > >> > is okay. but i've been told elsewhere that it is not okay.
    > >> > what is the case here? is it okay or not?
    > >>
    > >> The issue is that feof() only tells you AFTER you have
    > >> attempted to read past the end of the file. If you understand
    > >> that, and code accordingly, it is OK to use it, AFAIK.
    > >>
    > >> That is, if a file has n characters, you can read all of them
    > >> with fgets and feof() will still return zero (false). But if
    > >> you try to read n+1, then fgets will still succeed, but feof()
    > >> will return non-zero (true).

    > >
    > > Correction - that final fgets call will not succeed, it will
    > > return NULL. This may describe either the end-of-file, or a
    > > read error. feof() allows you to disambiguate them.

    >
    > I may not have expressed myself as clearly as I could have. The
    > bottom line, though, is that fgets will not return NULL if it
    > reads a few characters and THEN encounters eof. It will return
    > NULL when it encounters the end of the file without reading any
    > characters into the buffer. Unless I am reading the standard
    > wrong, which is certainly possible.


    The following covers fgets(). There is an additional provision
    somewhere that states that action on final file lines without a
    \n termination is undefined or implementation defined.

    From N869:

    7.19.7.2 The fgets function

    Synopsis

    [#1]
    #include <stdio.h>
    char *fgets(char * restrict s, int n,
    FILE * restrict stream);

    Description

    [#2] The fgets function reads at most one less than the
    number of characters specified by n from the stream pointed
    to by stream into the array pointed to by s. No additional
    characters are read after a new-line character (which is
    retained) or after end-of-file. A null character is written
    immediately after the last character read into the array.

    Returns

    [#3] The fgets function returns s if successful. If end-of-
    file is encountered and no characters have been read into
    the array, the contents of the array remain unchanged and a
    null pointer is returned. If a read error occurs during the
    operation, the array contents are indeterminate and a null
    pointer is returned.

    ____________________

    232An end-of-file and a read error can be distinguished by
    use of the feof and ferror functions.

    --
    Replies should be to the newsgroup
    Chuck Falconer, on vacation.
    LibraryUser, Sep 21, 2003
    #13
  14. LibraryUser <> wrote:

    >Mac wrote:

    <SNIP>
    >> I may not have expressed myself as clearly as I could have. The
    >> bottom line, though, is that fgets will not return NULL if it
    >> reads a few characters and THEN encounters eof. It will return
    >> NULL when it encounters the end of the file without reading any
    >> characters into the buffer. Unless I am reading the standard
    >> wrong, which is certainly possible.

    >
    >The following covers fgets(). There is an additional provision
    >somewhere that states that action on final file lines without a
    >\n termination is undefined or implementation defined.


    If this is correct, it would render fgets() almost useless for working
    on RealWorld(tm) files. May I kindly ask you where I can find the text
    you are referring to?

    >From N869:
    >
    > 7.19.7.2 The fgets function
    >
    > Synopsis
    >
    > [#1]
    > #include <stdio.h>
    > char *fgets(char * restrict s, int n,
    > FILE * restrict stream);
    >
    > Description
    >
    > [#2] The fgets function reads at most one less than the
    > number of characters specified by n from the stream pointed
    > to by stream into the array pointed to by s. No additional
    > characters are read after a new-line character (which is
    > retained) or after end-of-file. A null character is written
    > immediately after the last character read into the array.
    >
    > Returns
    >
    > [#3] The fgets function returns s if successful. If end-of-
    > file is encountered and no characters have been read into
    > the array, the contents of the array remain unchanged and a
    > null pointer is returned. If a read error occurs during the
    > operation, the array contents are indeterminate and a null
    > pointer is returned.


    IMO this implies that, as long as no error occured and at least one
    character has been read so far, fgets() returns a pointer to the
    buffer containing what have been read so far plus a terminating '\0'
    as soon as it encounters '\n' or EOF.

    Regards,

    Irrwahn
    --
    My other computer is a abacus.
    Irrwahn Grausewitz, Sep 21, 2003
    #14
  15. Mantorok Redgormor

    pete Guest

    Irrwahn Grausewitz wrote:
    >
    > LibraryUser <> wrote:


    > >The following covers fgets(). There is an additional provision
    > >somewhere that states that action on final file lines without a
    > >\n termination is undefined or implementation defined.

    >
    > If this is correct, it would render fgets() almost useless for working
    > on RealWorld(tm) files.
    > May I kindly ask you where I can find the text
    > you are referring to?
    >


    N869
    7.19.2 Streams
    [#2] A text stream is an ordered sequence of characters
    composed into lines, each line consisting of zero or more
    characters plus a terminating new-line character. Whether
    the last line requires a terminating new-line character is
    implementation-defined.

    --
    pete
    pete, Sep 22, 2003
    #15
  16. On Mon, 22 Sep 2003 03:41:05 GMT, pete <> wrote:

    >Irrwahn Grausewitz wrote:
    >>
    >> LibraryUser <> wrote:

    >
    >> >The following covers fgets(). There is an additional provision
    >> >somewhere that states that action on final file lines without a
    >> >\n termination is undefined or implementation defined.

    >>
    >> If this is correct, it would render fgets() almost useless for working
    >> on RealWorld(tm) files.
    >> May I kindly ask you where I can find the text
    >> you are referring to?
    >>

    >
    >N869
    >7.19.2 Streams
    > [#2] A text stream is an ordered sequence of characters
    > composed into lines, each line consisting of zero or more
    > characters plus a terminating new-line character. Whether
    > the last line requires a terminating new-line character is
    > implementation-defined.


    That makes the requirement for a final '\n' in the stream
    implementation specific. It in no way implies that fgets has any
    flexibility on how it process the final line. fgets is required to

    read at most n-1 bytes
    stop after reading and retaining an '/n' or after reaching eof
    return the array address in all cases except
    eof encountered without transferring any data
    a read error occurs

    Nowhere in the standard is any implementation-defined or undefined
    behavior specifically described for fgets. This includes the case
    where the stream does not terminate with a '\n', whether required to
    or not.

    One could argue that if the implementation requires the final '\n' in
    the stream and it is not present then attempting to read this line
    invokes undefined behavior because the stream is not well formed. But
    that has nothing to do with fgets and should apply equally to any I/O
    function attempting to read the stream.


    <<Remove the del for email>>
    Barry Schwarz, Sep 22, 2003
    #16
  17. Mantorok Redgormor

    Richard Bos Guest

    pete <> wrote:

    > Irrwahn Grausewitz wrote:
    >
    > > If this is correct, it would render fgets() almost useless for working
    > > on RealWorld(tm) files.
    > > May I kindly ask you where I can find the text
    > > you are referring to?

    >
    > N869
    > 7.19.2 Streams
    > [#2] A text stream is an ordered sequence of characters
    > composed into lines, each line consisting of zero or more
    > characters plus a terminating new-line character. Whether
    > the last line requires a terminating new-line character is
    > implementation-defined.


    And note that this is true for all <stdio.h> functions, not just for
    fgets(). It this requirement applies to your system, it'll be true for
    all programs, and you'll be used to it.
    All the same, it's best practice to always write the newline anyway, if
    only to avoid the following syndrome:

    This is a program which doesn't terminate its last line with a
    #_wline.

    Richard
    Richard Bos, Sep 22, 2003
    #17
  18. Barry Schwarz <> wrote:

    >On Mon, 22 Sep 2003 03:41:05 GMT, pete <> wrote:

    <SNIP>
    >>
    >>N869
    >>7.19.2 Streams
    >> [#2] A text stream is an ordered sequence of characters
    >> composed into lines, each line consisting of zero or more
    >> characters plus a terminating new-line character. Whether
    >> the last line requires a terminating new-line character is
    >> implementation-defined.

    >
    >That makes the requirement for a final '\n' in the stream
    >implementation specific. It in no way implies that fgets has any
    >flexibility on how it process the final line. fgets is required to
    >
    > read at most n-1 bytes
    > stop after reading and retaining an '/n' or after reaching eof
    > return the array address in all cases except
    > eof encountered without transferring any data
    > a read error occurs
    >
    >Nowhere in the standard is any implementation-defined or undefined
    >behavior specifically described for fgets. This includes the case
    >where the stream does not terminate with a '\n', whether required to
    >or not.


    Goodness, what a relief! I was already worrying about having to rewrite
    all the code that makes use of fgets().

    <SNIP>

    Irrwahn
    --
    My other computer is a abacus.
    Irrwahn Grausewitz, Sep 22, 2003
    #18
  19. "Barry Schwarz" <> wrote in message
    news:bkm4vm$sf6$0@216.39.135.208...
    >
    > Nowhere in the standard is any implementation-defined or undefined
    > behavior specifically described for fgets.


    That's not quite true. There are certainly explicit requirements for the
    arguments passed to fgets(), lest UB occur.

    > This includes the case
    > where the stream does not terminate with a '\n', whether required to
    > or not.


    I prefer to think the behaviour on reading the last line of text is
    implementation defined.

    > One could argue that if the implementation requires the final '\n' in
    > the stream and it is not present then attempting to read this line
    > invokes undefined behavior because the stream is not well formed.


    I don't disagree, but sanity would dictate that there's no need to lump
    fgets() into the same basket as gets().

    [Aside: Dealing with null bytes via fgets() is much trickier than trailing
    newlines. Throw in non-sticky EOF and ...]

    > But that has nothing to do with fgets and should apply equally to any I/O
    > function attempting to read the stream.


    ITYM: that is not specific to fgets...

    --
    Peter
    Peter Nilsson, Sep 22, 2003
    #19
  20. Irrwahn Grausewitz wrote:

    > Barry Schwarz <> wrote:
    >
    >
    >> On Mon, 22 Sep 2003 03:41:05 GMT, pete <> wrote:

    >
    > <SNIP>
    >
    >>> N869
    >>> 7.19.2 Streams
    >>> [#2] A text stream is an ordered sequence of characters
    >>> composed into lines, each line consisting of zero or more
    >>> characters plus a terminating new-line character. Whether
    >>> the last line requires a terminating new-line character is
    >>> implementation-defined.

    >>
    >> That makes the requirement for a final '\n' in the stream
    >> implementation specific. It in no way implies that fgets has any
    >> flexibility on how it process the final line. fgets is required to
    >>
    >> read at most n-1 bytes
    >> stop after reading and retaining an '/n' or after reaching eof
    >> return the array address in all cases except
    >> eof encountered without transferring any data
    >> a read error occurs
    >>
    >> Nowhere in the standard is any implementation-defined or undefined
    >> behavior specifically described for fgets. This includes the case
    >> where the stream does not terminate with a '\n', whether required to
    >> or not.

    >
    >
    > Goodness, what a relief! I was already worrying about having to rewrite
    > all the code that makes use of fgets().
    >
    > <SNIP>
    >
    > Irrwahn

    Hi All
    There is another problem with feof() when used with functions like
    fscanf(). In code like below, you will not get an EOF and spin forever!

    while( ! feof(infile)) {
    fscanf( infile," %d", &in );
    }
    If the format "%d" fails, fscanf will NOT move forward and this code
    will hang. I just ran into this problem with working code and a
    corrupted file. fscanf returns the number of data converted, so what
    that for a NULL or less that you expected.

    Hope this helps
    Cliff
    mailto:
    Clifton R. Liles "Software to the Stars"
    Pearland, TX 77581
    - Speaking for myself! Standard disclaimer applies. -
    This address may *not* be used for unsolicited mailings.
    Failure is not an option. It comes bundled with your Microsoft product.
    Clifton Liles, Sep 22, 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. Joriveek

    feof

    Joriveek, Sep 13, 2005, in forum: C Programming
    Replies:
    8
    Views:
    698
    Keith Thompson
    Sep 14, 2005
  2. question about gets() and feof().

    , Sep 16, 2005, in forum: C Programming
    Replies:
    3
    Views:
    345
    Simon Biber
    Sep 16, 2005
  3. ehui928

    A question about fscanf and feof !

    ehui928, Oct 15, 2006, in forum: C Programming
    Replies:
    7
    Views:
    3,114
    Joe Wright
    Nov 7, 2006
  4. rCs

    EOF vs. feof() and ferror()

    rCs, Oct 31, 2006, in forum: C Programming
    Replies:
    8
    Views:
    1,742
    Barry Schwarz
    Nov 1, 2006
  5. ericunfuk

    feof(), fseek(), fread()

    ericunfuk, Mar 24, 2007, in forum: C Programming
    Replies:
    20
    Views:
    2,387
    Joe Wright
    Mar 27, 2007
Loading...

Share This Page