473,395 Members | 1,341 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,395 software developers and data experts.

"inFile" object cannot read EOF

Hello. I'm studying the book "C++ Primer Plus" by Stephan Prata. In
chapter 6 he gives an exercise that reads from a file. The list is
thus:

4
Sam Stone
2000
Freida Flass
100500
Tammy Tubbs
5000
Rich Raptor
55000

So I create a istream object, inFile, and associate the file with
it. I know it reads the file because I've placed cout directives
after every read instruction. (since taken out). But I can't get the
program to read EOF.

After the following code there are conditions that test for
inFile.eof() and inFile.fail() but these get skipped over, to a
default "else" condition.

Can anyone see why EOF is not being recognized?
inFile >size;
donor *pd = new donor[size];
while(inFile.get() != '\n')
;

for(int i = 0; i < size; i++){
getline(inFile, pd[i].name); //a cout stmt here and
inFile >pd[i].cash; //here lets me know the data was
read
while(inFile.get() != '\n')
;
}

Jun 7 '07 #1
15 2966
waltbrad wrote:
Hello. I'm studying the book "C++ Primer Plus" by Stephan Prata. In
chapter 6 he gives an exercise that reads from a file. The list is
thus:

4
Sam Stone
2000
Freida Flass
100500
Tammy Tubbs
5000
Rich Raptor
55000

So I create a istream object, inFile, and associate the file with
it. I know it reads the file because I've placed cout directives
after every read instruction. (since taken out). But I can't get the
program to read EOF.
What do you mean by "to read EOF"? What's "EOF" in your statement?
After the following code there are conditions that test for
inFile.eof() and inFile.fail() but these get skipped over, to a
default "else" condition.
This is covered in the FAQ 5.8.
Can anyone see why EOF is not being recognized?
Every read operation ends with some kind of terminator. For example,
reading a number ('pd[i].cash') terminates at a symbol that cannot
be part of a number (like a newline). Most likely you never attempt
to read when the file cursor is _at_ the end of the file, to force the
'eof' bit to be set. Since you tell your program exactly how many
times to read, it doesn't fail to read, and that's why 'fail' bit is
not getting set either. Try removing the newline after the last
number in your file - make the third '0' in '55000' the _last_ symbol
in the file. You should see the difference.
>

inFile >size;
donor *pd = new donor[size];
while(inFile.get() != '\n')
;

for(int i = 0; i < size; i++){
getline(inFile, pd[i].name); //a cout stmt here and
inFile >pd[i].cash; //here lets me know the data was
read
while(inFile.get() != '\n')
;
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 7 '07 #2
On Jun 7, 2:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>
This is covered in the FAQ 5.8.
Hello again. Thanks for the response. Actually I was getting around to
your answer. But, you confirmed my suspicions, and I didn't know a way
to test them.

I waasn't aware that there was a faq for this newsgroup. Where can I
find it?

Thanks again.

Jun 7 '07 #3
waltbrad wrote:
>
I waasn't aware that there was a faq for this newsgroup. Where can I
find it?
http://www.parashift.com/c++-faq-lite/

DN
--
[there are no x's in my email]

I have the right to remain silent
(and should probably use it as much as possible)
Anything I type can and will be used against me
in a court of idiocy
I have the right to be wrong
(and probably am)
If I can not furnish my own wrongness
I'm sure someone will provide it for me.
Jun 7 '07 #4
waltbrad wrote:
On Jun 7, 2:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>>
This is covered in the FAQ 5.8.

Hello again. Thanks for the response. Actually I was getting around to
your answer. But, you confirmed my suspicions, and I didn't know a way
to test them.

I waasn't aware that there was a faq for this newsgroup. Where can I
find it?
http://www.parashift.com/c++-faq-lite/

Also, check out "Welcome to comp.lang.c++" message posted here every
now and then. If your server doesn't have it, search the archives.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 7 '07 #5
waltbrad wrote:
>
I waasn't aware that there was a faq for this newsgroup. Where can I
find it?
http://www.parashift.com/c++-faq-lite/

Mostly a great reference for a lot of concepts in C++, but has a section
devoted entirely to posting in this NG.

DN
--
[there are no x's in my email]

I have the right to remain silent
(and should probably use it as much as possible)
Anything I type can and will be used against me
in a court of idiocy
I have the right to be wrong
(and probably am)
If I can not furnish my own wrongness
I'm sure someone will provide it for me.
Jun 7 '07 #6
On Jun 7, 8:52 pm, waltbrad <waltb...@hotmail.comwrote:
Hello. I'm studying the book "C++ Primer Plus" by Stephan Prata. In
chapter 6 he gives an exercise that reads from a file. The list is
thus:
4
Sam Stone
2000
Freida Flass
100500
Tammy Tubbs
5000
Rich Raptor
55000
So I create a istream object, inFile, and associate the file with
it. I know it reads the file because I've placed cout directives
after every read instruction. (since taken out). But I can't get the
program to read EOF.
You can't "read" EOF, since by definition, a read fails if the
file is at EOF. You have to try to read something, and then
check whether it failed. After failure, you can check whether
it was due to EOF, or some other reason.
After the following code there are conditions that test for
inFile.eof() and inFile.fail() but these get skipped over, to a
default "else" condition.
I would help if you'd show them, however...
Can anyone see why EOF is not being recognized?
inFile >size;
donor *pd = new donor[size];
while(inFile.get() != '\n')
;
Why not simply: inFile.ignore( INT_MAX, '\n' ) ?

More generally, your file is line oriented, so it is probably
better to read it line by line, using an istringstream to
convert the numeric values (and verifying that the format is
correct). So the above would read:

std::string line ;
if ( ! std::getline( inFile, line ) ) {
// Error, file was empty...
}
std::istringstream sLine( line ) ;
if ( ! (sLine >size >std::ws) || sLine.get() != EOF ) {
// Error, first line didn't contain a number, or
// had extra junk at the end...
}

Given that your format includes lines with just a single number,
I'd probably wrap this into a separate function.

Finally, there's no reason in C++ to have to specify the count
at the start. Just use std::vector, and push_back until you
encounter end of file.
for(int i = 0; i < size; i++){
getline(inFile, pd[i].name); //a cout stmt here and
inFile >pd[i].cash; //here lets me know the data was
read
while(inFile.get() != '\n')
;
}
I'd write this loop something like:

std::vector< donor donors ;
std::string line1 ;
std::string line2 ;
while ( getline( inFile, line1 ) && getline( inFile, line2 ) ) {
double cash ;
std::istringstream sCash( line2 ) ;
sCash >cash ;
donors.push_back( donor( line1, cash ) ) ;
}

Except, of course, that it requires more error handling; the
above only works if the file has the correct format.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 8 '07 #7
On Jun 7, 10:51 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
waltbrad wrote:
On Jun 7, 2:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
This is covered in the FAQ 5.8.
Hello again. Thanks for the response. Actually I was getting around to
your answer. But, you confirmed my suspicions, and I didn't know a way
to test them.
I waasn't aware that there was a faq for this newsgroup. Where can I
find it?
http://www.parashift.com/c++-faq-lite/
Also, check out "Welcome to comp.lang.c++" message posted here every
now and then. If your server doesn't have it, search the archives.
Note that all of the FAQ's, to all groups, are available at
www.faqs.org. Back in the old days, this was pointed out to
people when they got their connection, but any sort of
responsability on the part of providers today seems to have gone
out the window.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 8 '07 #8

James Kanze wrote in message...
>** You can't "read" EOF **, since by definition, a read fails if the
file is at EOF.
So, my docs are wrong?
" Method: int istream::get ()
Read a single character ** (or EOF) ** from the input stream, returning it
(coerced to an unsigned char) as the result. "
You have to try to read something, and then
check whether it failed. After failure, you can check whether
it was due to EOF, or some other reason.
I once did this in some 'test' code:

// std::vector<unsigned charImage;
while( SomeInFile.peek() != EOF ){
// .... do stuff ....
// Image.push_back( SomeInFile.get() );
// if not reading single chars, need to check stream state.
}

Maybe it will help the OP to see the light. <G>

--
Bob R
POVrookie
Jun 8 '07 #9
BobR wrote:
James Kanze wrote in message...
>** You can't "read" EOF **, since by definition, a read fails if the
file is at EOF.

So, my docs are wrong?
" Method: int istream::get ()
Read a single character ** (or EOF) ** from the input stream,
returning it (coerced to an unsigned char) as the result. "
Whoever wrote that decided to shorten it a bit. What it should say
is "Read a single character from the input stream returning it, or
return a special value if the stream is in 'end-of-file' state".

In fact, istream::get() returns either the character it read or
'traits::eof()', according to the Standard. It doesn't "read" any
"EOF" from the stream.
> You have to try to read something, and then
check whether it failed. After failure, you can check whether
it was due to EOF, or some other reason.

I once did this in some 'test' code:

// std::vector<unsigned charImage;
while( SomeInFile.peek() != EOF ){
// .... do stuff ....
// Image.push_back( SomeInFile.get() );
// if not reading single chars, need to check stream state.
}

Maybe it will help the OP to see the light. <G>
Maybe...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 8 '07 #10

Victor Bazarov wrote in message...
BobR wrote:
James Kanze wrote in message...
** You can't "read" EOF **, since by definition, a read fails if the
file is at EOF.
So, my docs are wrong?
" Method: int istream::get ()
Read a single character ** (or EOF) ** from the input stream,
returning it (coerced to an unsigned char) as the result. "

Whoever wrote that decided to shorten it a bit. What it should say
is "Read a single character from the input stream returning it, or
return a special value if the stream is in 'end-of-file' state".
Ok, I'll buy that. Thanks.
>
In fact, istream::get() returns either the character it read or
'traits::eof()', according to the Standard. It doesn't "read" any
"EOF" from the stream.
No "implementation defined" escape clause there? I'll check it out (for my
systems(win,GNU)) to satisfy my curiosity <G>.

--
Bob R
POVrookie
Jun 8 '07 #11
On Jun 8, 8:20 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
James Kanze wrote in message...
** You can't "read" EOF **, since by definition, a read fails if the
file is at EOF.
So, my docs are wrong?
" Method: int istream::get ()
Read a single character ** (or EOF) ** from the input stream, returning it
(coerced to an unsigned char) as the result. "
Pourly worded. It "tries" to read a single character, returning
the character read, or EOF if it cannot read a character. EOF
is not a character, but a special out of band value. (That's
why get() returns int, and not char.)
You have to try to read something, and then
check whether it failed. After failure, you can check whether
it was due to EOF, or some other reason.
I once did this in some 'test' code:
// std::vector<unsigned charImage;
while( SomeInFile.peek() != EOF ){
// .... do stuff ....
// Image.push_back( SomeInFile.get() );
// if not reading single chars, need to check stream state.
}
Maybe it will help the OP to see the light. <G>
Yes. That's basically what I recommended at the filebuf level:
peek() simply returns rdbuf()->sgetc() (or EOF, if the rdbuf()
returns a null pointer).

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 8 '07 #12
On Jun 8, 10:42 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
Victor Bazarov wrote in message...
BobR wrote:
James Kanze wrote in message...
>** You can't "read" EOF **, since by definition, a read fails if the
>file is at EOF.
So, my docs are wrong?
" Method: int istream::get ()
Read a single character ** (or EOF) ** from the input stream,
returning it (coerced to an unsigned char) as the result. "
Whoever wrote that decided to shorten it a bit. What it should say
is "Read a single character from the input stream returning it, or
return a special value if the stream is in 'end-of-file' state".
Ok, I'll buy that. Thanks.
The important point is that at this level, EOF is an out of band
value, and not a character. At this level, because...
In fact, istream::get() returns either the character it read or
'traits::eof()', according to the Standard. It doesn't "read" any
"EOF" from the stream.
No "implementation defined" escape clause there? I'll check it
out (for my systems(win,GNU)) to satisfy my curiosity <G>.
Most of what takes place in IO is more or less "implementation
defined". When it's not flattly unspecified In particular, how
an implementation represents line breaks and end of file is
unspecified, and may (and does under most systems) differ
between text files and binary. (For Unix, everything is pretty
much transparent, and there is no EOF character, either in text
or in binary files. I think that most Windows compilers,
however, still recognize the traditional CP/M end of file
character, 0x1A, in text files.)

Note that historically, a common error was writing the result of
istream::get() or istream::peek() (or earlier, getc() or
getchar()) to a char, and testing that for EOF (typically -1,
although any negative value is legal). This worked if (and only
if) plain char was signed, and the file never contained a 0xFF.
In ISO 8859-1, 0xFF is the 'ÿ' character (small Latin letter y
with diarese, if it doesn't show up right here). Not the most
common character, so the error often went unobserved.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 8 '07 #13
In article <11**********************@q66g2000hsg.googlegroups .com>,
ja*********@gmail.com says...

[ ... ]
I'd write this loop something like:

std::vector< donor donors ;
std::string line1 ;
std::string line2 ;
while ( getline( inFile, line1 ) && getline( inFile, line2 ) ) {
double cash ;
std::istringstream sCash( line2 ) ;
sCash >cash ;
donors.push_back( donor( line1, cash ) ) ;
}
Personally, I think I'd do it a bit differently:

struct donor {
std::string name;
double cash;

// read a single donor's data:
friend std::istream &operator>>(std::istream &i, donor &d) {
std::getline(i, d.name);

std::string line2;
std::getline(line2);
std::istringstream temp(line2);
line2 >d.cash;
return i;
}
};

std::vector<donordonors;

std::copy(std::istream_iterator<donor>(infile),
std::istream_iterator<donor>(),
std::back_inserter(donors));

This does not require (or allow) the count at the beginning of the file
though...

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 10 '07 #14
On Jun 10, 2:23 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <1181292953.700106.187...@q66g2000hsg.googlegroups .com>,
james.ka...@gmail.com says...
[ ... ]
I'd write this loop something like:
std::vector< donor donors ;
std::string line1 ;
std::string line2 ;
while ( getline( inFile, line1 ) && getline( inFile, line2 ) ) {
double cash ;
std::istringstream sCash( line2 ) ;
sCash >cash ;
donors.push_back( donor( line1, cash ) ) ;
}
Personally, I think I'd do it a bit differently:
I'd do it a lot differently in production code as well:-).
Starting with a lot more error handling.
struct donor {
std::string name;
double cash;
// read a single donor's data:
friend std::istream &operator>>(std::istream &i, donor &d) {
std::getline(i, d.name);

std::string line2;
std::getline(line2);
std::istringstream temp(line2);
line2 >d.cash;
return i;
}
};
Good point. Using a >operator is definitely the way to go.
std::vector<donordonors;
std::copy(std::istream_iterator<donor>(infile),
std::istream_iterator<donor>(),
std::back_inserter(donors));
This does not require (or allow) the count at the beginning of the file
though...
Neither did my version:-). In fact, as soon as you use
std::vector, you're freed from this constraint.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 10 '07 #15
In article <11*********************@k79g2000hse.googlegroups. com>,
ja*********@gmail.com says...
On Jun 10, 2:23 am, Jerry Coffin <jcof...@taeus.comwrote:
[ ... ]
Personally, I think I'd do it a bit differently:

I'd do it a lot differently in production code as well:-).
Starting with a lot more error handling.
Well yes, I'd hope so -- but I was talking about basic structure, and
(at least in theory) the error handling shouldn't affect that a whole
lot. Of course, the ability to do exactly that is one of the biggest
arguments in favor of exception handling...

[ ... ]
This does not require (or allow) the count at the beginning of the file
though...

Neither did my version:-). In fact, as soon as you use
std::vector, you're freed from this constraint.
Right -- of course, you can avoid it without using std::vector, if you
want to badly enough. Chances are, however, that the firt several times
you try, you won't do the job as well as std::vector does...

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 11 '07 #16

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

Similar topics

1
by: questioner | last post by:
Hi folks, Id appreciate if you can help: I want to start an exe which takes as an argument filename. What I tried was: os.spawnl(os.P_NOWAIT,('processor.exe'),'filename.ext')) I also...
2
by: Luis | last post by:
the assignment is to count the number of words in a txt file here is my code #include <iostream> #include <fstream> #include <cassert> using namespace std; int main () {
9
by: mahurshi | last post by:
i have a quick question i am putting a debug flag in my program (i really dont need this feature, but i figured it might be useful when i get into trouble) so i want to check if argv is the...
8
by: Ian Davies | last post by:
Hello I have the following sql string to run as a command in my VB6 project to update mysql table strSQL = "LOAD DATA INFILE " & ImportFile & " INTO TABLE tPupils FIELDS TERMINATED BY ','...
7
by: jccorreu | last post by:
I've got to read info from multiple files that will be given to me. I know the format and what the data is. The thing is each time we run the program we may be using a differnt number of files,...
1
by: Parsed Cheese | last post by:
After two days I am at wits end, but I am too OCD'ed to give up. Please tell me what I have got wrong because no Validation Error is being thrown. The element: "<datestamp>I should...
10
by: jonathanemil | last post by:
Hello, I am a 1st semester Computer Science student in a Python class. Our current assignment calls for us to read a list from a file, create a 2-dimensional list from the file, and check to see...
11
by: MC | last post by:
I have a couple of customers who are using a program that deserializes an XML file, and on some files, the program fails to see the content of the file -- treats it as zero length and reports "root...
1
by: aberry | last post by:
I have text file which contain Unicode data (say inp.txt) I read file using following code:- import codecs infile = codecs.open('C:\\tdata\\inp.txt','r','utf-16',errors='ignore') data =...
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
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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
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...

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.