473,386 Members | 2,078 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

EOF for binary files

I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input. Instead, you can
use the library function feof(), which can be used for both binary- and
text-mode files:

int feof(FILE *fp);
</quote>

Isn't it true that testing for EOF is valid for both text- and
binary-mode files?

Also, the FAQ recommends not to use feof():
<quote>In virtually all cases, there's no need to use feof at all.
</quote>

Nov 11 '06 #1
12 16111
Registered User said:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.
Ditch the book. It doesn't understand EOF.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 11 '06 #2
Richard Heathfield wrote:
Registered User said:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.

Ditch the book. It doesn't understand EOF.
Oh, thanks Richard!! That part of the book really got me confused.

Nov 11 '06 #3
Registered User said:
Richard Heathfield wrote:
>Registered User said:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.

Ditch the book. It doesn't understand EOF.
Oh, thanks Richard!! That part of the book really got me confused.
The mistake the author makes is that he appears to believe EOF is a
character. It isn't. It's a message from your I/O library which, freely
translated, means "you asked me for more data, squire, but there ain't
none. The pot's empty. Sorry, I'd love to help and all that...".

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 11 '06 #4
Registered User wrote:
>
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by
looking for EOF, because a byte of data from a binary stream could
have that value, which would result in premature end of input.
Instead, you can use the library function feof(), which can be
used for both binary- and text-mode files:

int feof(FILE *fp);
</quote>

Isn't it true that testing for EOF is valid for both text- and
binary-mode files?
Yes. The only possible exception occurs when (sizeof(int) == 1).
A stream is a stream of bytes, and the routines to read them return
ints formed from the (unsigned)char value involved. Thus the value
of EOF is always distinct.
>
Also, the FAQ recommends not to use feof():
<quote>In virtually all cases, there's no need to use feof at all.
</quote>
feof is primarily useful to distinguish between i/o errors and
actual eof, either of which conditions will usually return EOF.

if (EOF == (ch = getc(f))) {
if (feof(f)) /* actual file eof encountered */
else {
/* use ferror etc. to determine the cause */
}
}
else {
/* use the value of ch, which is a valid unsigned char */
}

note that ch must have been declared as an int.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Nov 11 '06 #5
In article <11**********************@m73g2000cwd.googlegroups .com>,
Registered User <in*******************@gmail.comwrote:
>With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.
It would certainly be a mistake to compare a byte against EOF if the
byte is a char, because EOF is an int value and a char converted to
an int might have the same value as EOF. But getc() doesn't return
a char; it returns an unsigned char converted to an int, so there
is no possibility of a real byte appearing to be equal to EOF, because
EOF is guaranteed to be negative.

So you can perfectly well compare against EOF provided you don't
convert the value to a char first.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Nov 11 '06 #6
Registered User wrote:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input. Instead, you can
use the library function feof(), which can be used for both binary- and
text-mode files:

int feof(FILE *fp);
</quote>

Isn't it true that testing for EOF is valid for both text- and
binary-mode files?
The book is right in the sense that it is possible for a
byte read from a stream (text or binary) to have the value
EOF, but only on "exotic" machines where bytes and ints have
the same size. That is, the book is right if it's trying to
be "fully general" -- but if it's writing about "mainstream"
C implementations it's wrong.

The Standard defines all input operations as if they used
the fgetc() function as many times as necessary (the actual
implementation might do something more intricate, but the end
result must be the same). The fgetc() function returns an int
value: either EOF to indicate failure, or an actual input byte
represented as unsigned char converted to int. If int is
wider than char, converting an unsigned char to an int yields
a non-negative value, and since the EOF macro expands to a
negative number there can be no confusion.

On those exotic architectures, though, things get sticky.
If sizeof(int) == 1, there must be unsigned char values that
are too large for int: for example, on a system with sixteen-bit
chars and sixteen-bit ints, INT_MAX will be 32767 but UCHAR_MAX
will be 65535. Since fgetc() must be able to read back any
character values fputc() might have written (subject to some
restrictions that don't matter here), on this system it must
be able to return 65536 distinguishable int values. Half of
those will necessarily be negative, and one of them will have
the same value as EOF. So on exotic architectures, it is
possible for fgetc() to return EOF when reading "real" data,
and the only way to tell whether the EOF is actual data or an
indication of input failure is to call both feof() and ferror().
Also, the FAQ recommends not to use feof():
<quote>In virtually all cases, there's no need to use feof at all.
</quote>
I'm not the FAQ author, but I'd read "in virtually all cases"
to mean "whenever int is wider than char," or "on virtually all
`mainstream' machines." It would be nice, IMHO, if the FAQ were
more explicit about this, but it's not a big failing.

The FAQ is right in implying that feof() is seldom used,
because after receiving an EOF return value (on a "mainstream"
system) your immediate concern should be "End-of-input, or error?"
and it seems more natural to use ferror() for that question:

int ch;
while ( (ch = fgetc(stream)) != EOF ) {
/* process the character just read */
}
/* "Why did we get EOF?" */
if (ferror(stream)) {
/* do something about the I/O error */
}
else {
/* normal end-of-input */
}

This code assumes that EOF can only appear as the result of
end-of-input or I/O error, so if there's no I/O error the stream
must have reached its end. Of course, the same reasoning would
hold for using feof(stream) and swapping the bodies of the two
if statements, but "ferror?" seems a more direct inquiry.

On "exotic" architectures the either/or reasoning breaks down
because there's a third possibility: an EOF return might be actual
input data. If you're writing with such a system in mind you need
to use both feof() and ferror() to distinguish the three outcomes,
and the loop might look something like

int ch;
while ( (ch = fgetc(stream)) , /* comma operator */
(!feof(stream) && !ferror(stream) ) {
/* process the character just read */
}
/* "Was it error or end-of-input?" */
if (ferror(stream)) {
/* do something about the I/O error */
}
else {
/* normal end-of-input */
}

Of course, this can be written in many other rearrangements. One
likely change would be to call feof() and ferror() only when an EOF
shows up instead of every single time, by changing the while clause
to something like

while ( (ch = fgetc(stream)) != EOF
|| (!feof(stream) && !ferror(stream)) )

Since most I/O devices are pathetically slow compared to most CPUs,
this "optimization" probably doesn't save noticeable time -- but
it is in the tradition of C to worry about tiny efficiencies while
ignoring gross waste. ;-) (That same tradition, by the way, calls
for using getc() instead of fgetc() wherever possible.)

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 11 '06 #7
Op 11 Nov 2006 14:34:44 GMT schreef Richard Tobin:
In article <11**********************@m73g2000cwd.googlegroups .com>,
Registered User <in*******************@gmail.comwrote:
>>With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.

It would certainly be a mistake to compare a byte against EOF if the
byte is a char, because EOF is an int value and a char converted to
an int might have the same value as EOF. But getc() doesn't return
a char; it returns an unsigned char converted to an int, so there
is no possibility of a real byte appearing to be equal to EOF, because
EOF is guaranteed to be negative.
getc returns an int, not a char, be it signed or unsigned.
#include <stdio.h>
int getc(FILE *FP);
And yes, if no EOF condition is reached, the int may be regarded as char.
EOF does not fit in a char so it well may be some negative number.
So you can perfectly well compare against EOF provided you don't
convert the value to a char first.
Yes.
--
Coos
Nov 11 '06 #8
Coos Haak wrote:
Op 11 Nov 2006 14:34:44 GMT schreef Richard Tobin:
>In article <11**********************@m73g2000cwd.googlegroups .com>,
Registered User <in*******************@gmail.comwrote:
>>With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.
It would certainly be a mistake to compare a byte against EOF if the
byte is a char, because EOF is an int value and a char converted to
an int might have the same value as EOF. But getc() doesn't return
a char; it returns an unsigned char converted to an int, so there
is no possibility of a real byte appearing to be equal to EOF, because
EOF is guaranteed to be negative.

getc returns an int, not a char, be it signed or unsigned.
Richard said that.
#include <stdio.h>
int getc(FILE *FP);
And yes, if no EOF condition is reached, the int may be regarded as char.
Be *definition* if EOF is not returned the value is that of an
*unsigned* char as, again, richard said.
EOF does not fit in a char so it well may be some negative number.
EOF is *defined* as being a negative number, so there is no "may well
be" about it.
>So you can perfectly well compare against EOF provided you don't
convert the value to a char first.

Yes.
Everything Richard said in that post is correct, not just that last
sentence.
--
Flash Gordon
Nov 11 '06 #9
Op Sat, 11 Nov 2006 17:21:14 +0000 schreef Flash Gordon:
Coos Haak wrote:
>Op 11 Nov 2006 14:34:44 GMT schreef Richard Tobin:
>>In article <11**********************@m73g2000cwd.googlegroups .com>,
Registered User <in*******************@gmail.comwrote:

With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input.
It would certainly be a mistake to compare a byte against EOF if the
byte is a char, because EOF is an int value and a char converted to
an int might have the same value as EOF. But getc() doesn't return
My mistake, I overlooked this -------
Sorry for reading and replying too fast and hasty ;-(
--
Coos
Nov 11 '06 #10
"Registered User" <in*******************@gmail.comwrites:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input. Instead, you can
use the library function feof(), which can be used for both binary- and
text-mode files:

int feof(FILE *fp);
</quote>
Who is the author? If it's Schildt, we already know about him (and
warn people away from his books whenever possible). If it's someone
else, we may have another name for The List.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 11 '06 #11
"Registered User" <in*******************@gmail.comwrote:
# I've read in a book:
#
# <quote>
# With a binary-mode stream, you can't detect the end-of-file by looking
# for EOF, because a byte of data from a binary stream could have that
# value, which would result in premature end of input. Instead, you can
# use the library function feof(), which can be used for both binary- and
# text-mode files:

It's referring to getw(fp) which can return the same value as EOF
without actually being at the end of file.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
The little stoner's got a point.
Nov 11 '06 #12
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrites:
"Registered User" <in*******************@gmail.comwrote:
I've read in a book:

<quote>
With a binary-mode stream, you can't detect the end-of-file by looking
for EOF, because a byte of data from a binary stream could have that
value, which would result in premature end of input. Instead, you can
use the library function feof(), which can be used for both binary- and
text-mode files:

It's referring to getw(fp) which can return the same value as EOF
without actually being at the end of file.
What makes you think it's referring to getw()? There is no such function
in standard C.

<OT>
There is a non-standard function getw() that reads a word (defined as
an int) from a stream. It's not even POSIX; it's defined by SVID, and
one man page recommends using fread() instead. The text quoted from
the book doesn't even make sense in terms of getw(), since it talks
about a *byte* of data having the value EOF.
</OT>

It's far more likely that the author of the book just doesn't know
what he's talking about.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 11 '06 #13

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

Similar topics

11
by: rbt | last post by:
Is there an easy way to exclude binary files (I'm working on Windows XP) from the file list returned by os.walk()? Also, when reading files and you're unsure as to whether or not they are ascii...
27
by: Eric | last post by:
Assume that disk space is not an issue (the files will be small < 5k in general for the purpose of storing preferences) Assume that transportation to another OS may never occur. Are there...
28
by: wwj | last post by:
void main() { char* p="Hello"; printf("%s",p); *p='w'; printf("%s",p); }
6
by: alice | last post by:
hi all, Can anybody please tell the advantages which the binary files offers over the character files. Thanks, Alice walls
4
by: knapak | last post by:
Hello I'm a self instructed amateur attempting to read a huge file from disk... so bear with me please... I just learned that reading a file in binary is faster than text. So I wrote the...
8
by: dagecko | last post by:
Hi I would like to know how to detect if a file is binary or not. It's important for me but I don't know where to start. Ty
10
by: joelagnel | last post by:
hi friends, i've been having this confusion for about a year, i want to know the exact difference between text and binary files. using the fwrite function in c, i wrote 2 bytes of integers in...
15
by: JoeC | last post by:
I am writing a program that I am trying to learn and save binary files. This is the page I found as a source: http://www.angelfire.com/country/aldev0/cpphowto/cpp_BinaryFileIO.html I have...
3
by: masood.iqbal | last post by:
Hi, Kindly excuse my novice question. In all the literature on ifstream that I have seen, nowhere have I read what happens if you try to read a binary file using the ">>" operator. I ran into...
9
by: deepakvsoni | last post by:
are binary files portable?
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...

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.