ifstream eof not reporting eof?

S

SpreadTooThin

I just did a loop

ifstream i(myfile, ios::binary);

while (!i.eof())
{
i.read(buff, 2);
}

Well it should have come out of the loop but it tried to do the read
operation again...
Now... I know I should have checked the return of the read, but read
returns an ifstream...
How do I go about checking that the data was actually read and what
the heck is wrong with eof?
 
S

SpreadTooThin

I just did a loop

ifstream i(myfile, ios::binary);

while (!i.eof())
{
i.read(buff, 2);

}

Well it should have come out of the loop but it tried to do the read
operation again...
Now... I know I should have checked the return of the read, but read
returns an ifstream...
How do I go about checking that the data was actually read and what
the heck is wrong with eof?

Reading the fine manual... It seems that eof will only be true after
you have tried to read and failed...
Pardon me but isn't that a bit silly?
 
V

Victor Bazarov

SpreadTooThin said:
I just did a loop

ifstream i(myfile, ios::binary);

while (!i.eof())
{
i.read(buff, 2);
}

Well it should have come out of the loop but it tried to do the read
operation again...
Huh?

Now... I know I should have checked the return of the read, but read
returns an ifstream...

So? 'ifstream' has 'good()' member, and it has conversion to 'void*',
so you can do

while (i.read(buff, 2))

or

while (i.read(buff, 2).good())
How do I go about checking that the data was actually read and what
the heck is wrong with eof?

Nothing the heck is wrong with eof. You probably don't understand
how to use it. Try RTFM. Pay specific attention to what flags are
set when 'read' succeeds and/or when it fails, or when it reads less
than requested. Then perform proper actions depending on the flags
you see set after calling 'read'. Also, get a decent book that has
unformatted I/O explained.

V
 
G

Gavin Deane

I just did a loop

ifstream i(myfile, ios::binary);

while (!i.eof())
{
i.read(buff, 2);

}

Well it should have come out of the loop but it tried to do the read
operation again...
Now... I know I should have checked the return of the read, but read
returns an ifstream...
How do I go about checking that the data was actually read and what
the heck is wrong with eof?

Nothing is wrong with eof as long as you use it in the right way -
which you aren't. Change your code to use eof as described in the FAQ
and see if that fixes your problem.
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.4
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5

Gavin Deane
 
V

Victor Bazarov

SpreadTooThin said:
Reading the fine manual... It seems that eof will only be true after
you have tried to read and failed...
Pardon me but isn't that a bit silly?

No. Why is it silly? 'eof' is an error condition that indicates some
specific state of the stream. The 'end-of-file' is not reached upon
a successful read operation. If it's successful, there is no error,
right?

V
 
R

Ron Natalie

SpreadTooThin wrote:
\
Reading the fine manual... It seems that eof will only be true after
you have tried to read and failed...
Pardon me but isn't that a bit silly?

Nope, that is the way a large plethora of underlying I/O systems
work. EOF isn't detectable unless you try to read something.
C++ takes this as a common denominator.
 
B

BobR

Ron Natalie said:
Nope, that is the way a large plethora of underlying I/O systems
work. EOF isn't detectable unless you try to read something.
C++ takes this as a common denominator.

Well, you can 'detect' it:

if( MyInFile.peek() == EOF ){/*....*/}

....but the 'peek()' is still a 'read', and that line is seldom usable.
<G>
 
J

James Kanze

Reading the fine manual... It seems that eof will only be true after
you have tried to read and failed...
Pardon me but isn't that a bit silly?

And how do you propose to implement anything else, given the
constraint of also supporting interactive devices, and input of
various types? Suppose the data left in the file is " \n".
What should i.eof() return in the following code:

if ( ! i.eof() ) {
if ( rand() % 1 == 0 ) {
char ch = i.get() ; // guaranteed, since ! i.eof()
} else {
int i ;
i >> ch ; // guaranteed, since ! i.eof()
}
}
 
J

James Kanze

SpreadTooThin wrote:

[...]
So? 'ifstream' has 'good()' member, and it has conversion to 'void*',
so you can do
while (i.read(buff, 2))

while (i.read(buff, 2).good())

No, no, no, no. There is *never* any time that ios::good()
should be used, since it returns false if eofbit is set (and so
may return false when the read actually succeeds).
Nothing the heck is wrong with eof.

Nothing that it would be possible to fix, you mean. A
predictive EOF would in fact be very nice. In the distant past,
some languages (e.g. Pascal) have tried to specify it. In the
end, it never worked correctly; it's nice, but no one knows how
to specify it so that it is both useful and implementable.
You probably don't understand
how to use it. Try RTFM. Pay specific attention to what flags are
set when 'read' succeeds and/or when it fails, or when it reads less
than requested.

And pay specific attention to what flags are tested by each
function as well:). The basic philosophy of not supporting
predictive EOF is quite justifiable, given the experience of
other languages. The choice and naming of the functions in ios
a lot less so.
 
J

James Kanze

Nothing is wrong with eof as long as you use it in the right way -
which you aren't. Change your code to use eof as described in the FAQ
and see if that fixes your problem.http://www.parashift.com/c++-faq-li...t.com/c++-faq-lite/input-output.html#faq-15.5

The case of binary input, as in his code, is a bit more awkward,
since there are two possible definitions of success: he read 2
bytes, or he read some bytes. The standard takes the first
definition: if i.read(buff,2) succeeds, (i.e. if
"i.read(buff,2)" is treated as true in an if or a while), then 2
bytes have actually been read, no more, no less. If you're
interested in partial reads, you have to do something like:

while ( i.read( buff, 2 ) || i.gcount() != 0 ) {
// ...
}

Note that this is only true for binary reads of (potentially)
more than one byte. In all other cases, the standard idiom
explained in the FAQ is good.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top