473,503 Members | 12,425 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

feof usage

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
Nov 13 '05 #1
28 11506
Mac
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
--
Nov 13 '05 #2
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

Nov 13 '05 #3
On 19 Sep 2003 19:11:20 -0700, ne*****@tokyo.com (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
Nov 13 '05 #4
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

Nov 13 '05 #5

"Mantorok Redgormor" <ne*****@tokyo.com> wrote in message
news:41**************************@posting.google.c om...
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
Nov 13 '05 #6
Mac
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
--
Nov 13 '05 #7
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.
Nov 13 '05 #8
Glen Herrmannsfeldt wrote:
"Mantorok Redgormor" <ne*****@tokyo.com> 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.
Nov 13 '05 #9

"LibraryUser" <de**********@made.invalid> wrote in message
news:3F***************@made.invalid...
Glen Herrmannsfeldt wrote:
"Mantorok Redgormor" <ne*****@tokyo.com> 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
Nov 13 '05 #10
Mac
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
--
Nov 13 '05 #11
In 'comp.lang.c', ne*****@tokyo.com (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- em**********@noos.fr [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/
Nov 13 '05 #12
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.
Nov 13 '05 #13
LibraryUser <de**********@made.invalid> 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.
Nov 13 '05 #14
Irrwahn Grausewitz wrote:

LibraryUser <de**********@made.invalid> 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
Nov 13 '05 #15
On Mon, 22 Sep 2003 03:41:05 GMT, pete <pf*****@mindspring.com> wrote:
Irrwahn Grausewitz wrote:

LibraryUser <de**********@made.invalid> 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>>
Nov 13 '05 #16
pete <pf*****@mindspring.com> 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
Nov 13 '05 #17
Barry Schwarz <sc******@deloz.net> wrote:
On Mon, 22 Sep 2003 03:41:05 GMT, pete <pf*****@mindspring.com> 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.
Nov 13 '05 #18
"Barry Schwarz" <sc******@deloz.net> wrote in message
news:bk**********@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
Nov 13 '05 #19


Irrwahn Grausewitz wrote:
Barry Schwarz <sc******@deloz.net> wrote:

On Mon, 22 Sep 2003 03:41:05 GMT, pete <pf*****@mindspring.com> 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: u0****@trip.net
Clifton R. Liles "Software to the Stars" li*****@acm.org
Pearland, TX 77581 c.*******@ieee.org u0****@trip.net
- 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.

Nov 13 '05 #20
On Mon, 22 Sep 2003 22:34:38 +1000, "Peter Nilsson"
<ai***@acay.com.au> wrote:
"Barry Schwarz" <sc******@deloz.net> wrote in message
news:bk**********@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.


I agree that bad arguments can cause UB but that's true for any
function. fgets appears in section J.2 only once (regarding an
attempt to use the array if fgets reports an I/O error) and that
section is not specific to fgets but includes other I/O functions.
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.


Implementation-defined implies there is more than one possible legal
behavior. If you think it is implementation defined, does your
implementation document it and, if so, as what? What other possible
behaviors are there that satisfy the standard? Can fgets return
something other than the array address? If the '\n' is not present in
the stream, can it stop reading before the end of file? Can it fail
to terminate the string with a '\0'? Can it add a '\n' of its own?
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.

Now that I think about it some more, I think this should be required
to be detected as an I/O error rather than undefined behavior.

I don't disagree, but sanity would dictate that there's no need to lump
fgets() into the same basket as gets().
I don't follow this. How does discussing what fgets does when it
processes an improperly formatted stream "lump it with gets"?

[Aside: Dealing with null bytes via fgets() is much trickier than trailing
newlines. Throw in non-sticky EOF and ...]
The standard does not indicate that fgets treats a '\0' in the input
stream different than any other non-'\n' character. In fact, there
are only three conditions (other than I/O error) that will terminate
the operation:
'\n' encountered in the stream
end of file encountered in the stream
n-1 characters read from the stream

What is a non-sticky EOF?

What does this have to do with how fgets processes the last line of a
text file?
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...


Yes.
<<Remove the del for email>>
Nov 13 '05 #21
Mac
On Tue, 23 Sep 2003 03:31:32 +0000, Barry Schwarz wrote:
On Mon, 22 Sep 2003 22:34:38 +1000, "Peter Nilsson"
<ai***@acay.com.au> wrote:


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


The standard does not indicate that fgets treats a '\0' in the input
stream different than any other non-'\n' character. In fact, there
are only three conditions (other than I/O error) that will terminate
the operation:
'\n' encountered in the stream
end of file encountered in the stream
n-1 characters read from the stream


I think the problem is, how do you know what is after the nul? fgets()
doesn't return anything that lets you know how many characters you've
read, and strlen() will be fooled by the nul. So, unless you specifically
write your code to deal with that, whatever is after the nul will be lost.
I've never thought of that before reading this thread, but I'm sure that
is what Peter Nilsson must be referring to. (right?)

Of course, people who embed nul's in text files should be shot anyway...

Mac
--
Nov 13 '05 #22
Clifton Liles wrote:

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.


This last bit is wrong. NULL is a pointer. Compare the return value from
fscanf to EOF or for fewer than the number of items you wanted converted,
if you want, but check the last code snippet below.

Only if end-of-file is encountered before any conversion is EOF returned.
So a matching error which is not properly diagnosed can lead to one of two
types of error:

Type (1) Endless loop
while (EOF != fscanf(infile, "%d", &in)) { /* whatever */ }

Type (2) Loop ends, but with EOF not detected in the loop:
while (1 != fscanf(infile, "%d", *in)) { /* whatever */ }
/* but feof(infile) and ferror(infile) can be used here, after
the loop */

Consider a loop like this, to be fleshed out later:
{
int count;
while (1)
{
count = fscanf(infile,"%d", *in));
if (feof(infile)) {
/* eof code, perhaps using the value count */
break;
}
else if (ferror(infile)) {
/* error code, perhaps using the value count */
break;
}
/* successful read code */
}
}


--
Martin Ambuhl

Nov 13 '05 #23
"Mac" <fo*@bar.net> wrote:
On Tue, 23 Sep 2003 03:31:32 +0000, Barry Schwarz wrote:
The standard does not indicate that fgets treats a '\0' in the input
stream different than any other non-'\n' character. In fact, there
are only three conditions (other than I/O error) that will terminate
the operation:
'\n' encountered in the stream
end of file encountered in the stream
n-1 characters read from the stream


I think the problem is, how do you know what is after the nul? fgets()
doesn't return anything that lets you know how many characters you've
read, and strlen() will be fooled by the nul. So, unless you specifically
write your code to deal with that, whatever is after the nul will be lost.
I've never thought of that before reading this thread, but I'm sure that
is what Peter Nilsson must be referring to. (right?)

Of course, people who embed nul's in text files should be shot anyway...

Files with embedded nul characters cannot considered to be text files.
And people reading binary files with fgets() should be shot... ;-)

Regards

Irrwahn
--
My other computer is an abacus.
Nov 13 '05 #24
Barry Schwarz wrote:
.... snip ...
What is a non-sticky EOF?

What does this have to do with how fgets processes the last
line of a text file?


An eof that "self-heals", such as provided by many
implementations of stdin when connected to the console. This
allows a user to signal EOF by such a key combination as CTL-Z or
CTL-D, and have that EOF condition disappear once reported.

I have used systems with sticky EOF, where signalling EOF on the
input console required contacting the system operator and
aborting the session before that terminal was of any further use
(for input). On todays systems the equivalent might be to
require a reboot.

There are arguments for and against such systems.

--
Replies should be to the newsgroup
Chuck Falconer, on vacation.
Nov 13 '05 #25
On Mon, 22 Sep 2003 22:36:25 -0700, "Mac" <fo*@bar.net> wrote:
On Tue, 23 Sep 2003 03:31:32 +0000, Barry Schwarz wrote:
On Mon, 22 Sep 2003 22:34:38 +1000, "Peter Nilsson"
<ai***@acay.com.au> wrote:

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


The standard does not indicate that fgets treats a '\0' in the input
stream different than any other non-'\n' character. In fact, there
are only three conditions (other than I/O error) that will terminate
the operation:
'\n' encountered in the stream
end of file encountered in the stream
n-1 characters read from the stream


I think the problem is, how do you know what is after the nul? fgets()
doesn't return anything that lets you know how many characters you've
read, and strlen() will be fooled by the nul. So, unless you specifically
write your code to deal with that, whatever is after the nul will be lost.
I've never thought of that before reading this thread, but I'm sure that
is what Peter Nilsson must be referring to. (right?)


While you can't use strchr or strstr, you can search the input buffer
for a '\n'. If you find it, you know that is where fgets stopped (or
at the '\0' in the following byte. If you don't find a '\n' and
feof() is false, then you know that exactly n-1 bytes were read in. I
don't know how to deal with the case where end or file is detected but
there is no '\n'.
Of course, people who embed nul's in text files should be shot anyway...


<<Remove the del for email>>
Nov 13 '05 #26
Mac
On Tue, 23 Sep 2003 13:16:10 +0200, Irrwahn Grausewitz wrote:
"Mac" <fo*@bar.net> wrote:
On Tue, 23 Sep 2003 03:31:32 +0000, Barry Schwarz wrote:
The standard does not indicate that fgets treats a '\0' in the input
stream different than any other non-'\n' character. In fact, there
are only three conditions (other than I/O error) that will terminate
the operation:
'\n' encountered in the stream
end of file encountered in the stream
n-1 characters read from the stream
I think the problem is, how do you know what is after the nul? fgets()
doesn't return anything that lets you know how many characters you've
read, and strlen() will be fooled by the nul. So, unless you specifically
write your code to deal with that, whatever is after the nul will be lost.
I've never thought of that before reading this thread, but I'm sure that
is what Peter Nilsson must be referring to. (right?)

Of course, people who embed nul's in text files should be shot anyway...

Files with embedded nul characters cannot considered to be text files.
And people reading binary files with fgets() should be shot... ;-)


OK, OK. How 'bout this: If it's supposed to be a text file, and someone
puts a nul in it, let's shoot him or her. But if it's supposed to be a
binary file, and the programmer is using fgets(), then we'll shoot the
programmer. This seems pretty fair to me. ;-)
Regards

Irrwahn


Mac
--
Nov 13 '05 #27
"Mac" <fo*@bar.net> wrote:
On Tue, 23 Sep 2003 13:16:10 +0200, Irrwahn Grausewitz wrote:
"Mac" <fo*@bar.net> wrote:
Of course, people who embed nul's in text files should be shot anyway...

Files with embedded nul characters cannot considered to be text files.
And people reading binary files with fgets() should be shot... ;-)


OK, OK. How 'bout this: If it's supposed to be a text file, and someone
puts a nul in it, let's shoot him or her. But if it's supposed to be a
binary file, and the programmer is using fgets(), then we'll shoot the
programmer. This seems pretty fair to me. ;-)


Definitely, yes. :D

Regards

Irrwahn
--
The best cure for insomnia is to get a lot of sleep.
Nov 13 '05 #28
On 22 Sep 2003 06:31:18 GMT, Barry Schwarz <sc******@deloz.net> wrote:
On Mon, 22 Sep 2003 03:41:05 GMT, pete <pf*****@mindspring.com> wrote:
Irrwahn Grausewitz wrote:

LibraryUser <de**********@made.invalid> 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?

[ 7.19.2p2 snipped ]
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
Agree so far, except for the typo.
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.

I would conclude that, although the requirement is not written 'shall'
(and is not in a constraint) so it might be arguable.

But this option exists primarily for the benefit of implementations on
systems where the files used for text, unless the plain-ASCII streams
of Unix and the MSDOS tribe, *cannot* store an unterminated last line.
On those systems, the UB for read never occurs; what matters is that
*writing* an unterminated last line to an output file does.

- David.Thompson1 at worldnet.att.net
Nov 13 '05 #29

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
2083
by: Wolfgang Werners-Lucchini | last post by:
Hallo! The code here outputs '0'. Why? ---------------------------- $filename = "test.dat"; if (!file_exists($filename)) { touch($filename); // Create blank file chmod($filename,0666); }...
11
5916
by: | last post by:
Hi all...this is a great forum, In one of my posts, someone tell me that is more secure use input function with 'A field-width specifier'... So my question, which function i should use ?. ...
8
14377
by: rCs | last post by:
Which of the following two approaches is preferred (and why)? int c; do { ... c = getchar(); } while (c != EOF); - or -
12
2397
by: Sankar | last post by:
Dear all, I am programming in Linux , wherein I need to know a couple of things. 1) Does an API exist that can copy file onto another file ( an API equivalent of 'cp') ? 2) Is there an API...
20
7478
by: ericunfuk | last post by:
If fseek() always clears EOF, is there a way for me to fread() from an offset of a file and still be able to detect EOF?i.e. withouting using fseek(). I also need to seek to an offset in the file...
24
5962
by: kindrain | last post by:
the code checks whether a.txt has exact the same lines, then write different lines into b.txt Here it is: (before that ,you should creat a.txt) ---------------------- #include<stdio.h>...
0
7212
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7364
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7470
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5604
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3174
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1524
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
751
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
405
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.