Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > feof usage

Reply
Thread Tools

feof usage

 
 
Mac
Guest
Posts: n/a
 
      09-21-2003
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
--
 
Reply With Quote
 
 
 
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      09-21-2003
In 'comp.lang.c', http://www.velocityreviews.com/forums/(E-Mail Removed) (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- (E-Mail Removed) [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/
 
Reply With Quote
 
 
 
 
LibraryUser
Guest
Posts: n/a
 
      09-21-2003
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.
 
Reply With Quote
 
Irrwahn Grausewitz
Guest
Posts: n/a
 
      09-21-2003
LibraryUser <(E-Mail Removed)> 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.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      09-22-2003
Irrwahn Grausewitz wrote:
>
> LibraryUser <(E-Mail Removed)> 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
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      09-22-2003
On Mon, 22 Sep 2003 03:41:05 GMT, pete <(E-Mail Removed)> wrote:

>Irrwahn Grausewitz wrote:
>>
>> LibraryUser <(E-Mail Removed)> 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>>
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      09-22-2003
pete <(E-Mail Removed)> 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
 
Reply With Quote
 
Irrwahn Grausewitz
Guest
Posts: n/a
 
      09-22-2003
Barry Schwarz <(E-Mail Removed)> wrote:

>On Mon, 22 Sep 2003 03:41:05 GMT, pete <(E-Mail Removed)> 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.
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      09-22-2003
"Barry Schwarz" <(E-Mail Removed)> 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


 
Reply With Quote
 
Clifton Liles
Guest
Posts: n/a
 
      09-22-2003


Irrwahn Grausewitz wrote:

> Barry Schwarz <(E-Mail Removed)> wrote:
>
>
>> On Mon, 22 Sep 2003 03:41:05 GMT, pete <(E-Mail Removed)> 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: (E-Mail Removed)
Clifton R. Liles "Software to the Stars" (E-Mail Removed)
Pearland, TX 77581 (E-Mail Removed) (E-Mail Removed)
- 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.



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
feof(), fseek(), fread() ericunfuk C Programming 20 03-27-2007 09:22 PM
A question about fscanf and feof ! ehui928 C Programming 7 11-07-2006 01:48 AM
EOF vs. feof() and ferror() rCs C Programming 8 11-01-2006 04:45 PM
question about gets() and feof(). sunnyboyGuo@gmail.com C Programming 3 09-16-2005 05:36 PM
feof Joriveek C Programming 8 09-14-2005 06:21 PM



Advertisments