473,569 Members | 2,691 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

ifstream question

Hi

I'm using ifstream (which I hardly ever use) to read an ascii text
file (containing numbers delimited by newlines) in a loop using
something like:

ifstream infile("filenam e")
int value;

infile >value;
while(!infile.e of() {
infile >value;
:

}

The problem is if the file is missing a terminating newline the final
number is missed. How can I make sure its read anyway when the newline
is missing?

Thanks for any help

B2003
Jan 29 '08 #1
7 3213
Alf P. Steinbach wrote:
* Boltar:
>>
I'm using ifstream (which I hardly ever use) to read an ascii text
file (containing numbers delimited by newlines) in a loop using
something like:

ifstream infile("filenam e")
int value;

infile >value;
while(!infile. eof() {
infile >value;
:

}

The problem is if the file is missing a terminating newline the final
number is missed. How can I make sure its read anyway when the newline
is missing?

Don't test for eof, test for good stream state, i.e. that last read was
successful.
The answer is in the FAQ:
http://www.parashift.com/c++-faq-lit....html#faq-15.5
Like

ifstream infile( "filename" );

for( ;; )
{
int value;

infile >value;
if( !infile.good() )
{
break;
}
// Do something with value.
}
if( !infile.eof() ) { /* oops. */ }
When I see this I start to believe, that break in loops is evil, as James
said. The example in the FAQ is not as ugly as this code.

--
Thomas
Jan 29 '08 #2

"Alf P. Steinbach" <al***@start.no wrote in message
news:13******** *****@corp.supe rnews.com...
* Boltar:
I'm using ifstream (which I hardly ever use) to read an ascii text
file (containing numbers delimited by newlines) in a loop using
something like:

ifstream infile("filenam e")
int value;

infile >value;
while(!infile.e of() {
infile >value;
:

}

The problem is if the file is missing a terminating newline the final
number is missed. How can I make sure its read anyway when the newline
is missing?

Don't test for eof, test for good stream state, i.e. that last read was
successful.

Like

ifstream infile( "filename" );

for( ;; )
{
int value;

infile >value;
if( !infile.good() )
{
break;
}
// Do something with value.
}
if( !infile.eof() ) { /* oops. */ }

Disclaimer: I really hate iostreams, so possibly that last check isn't
completely 100% cover-all-cases or guaranteed to detect failure.
Pardon, please, but:
Oh. Good. _Grief_!!
Alf, I just spent manydays trying to do exactly this above (get a number
from a file), but with a piece of code another kind poster provided ('cause
I was stumped) and I modified.
To wit:

/*usual headers and using n.s.*/
ifstream ifstr("tvrfile. tvr");
string txt("");
char *tmp;
getline( ifstr, txt, ',');
const int pNum(strtod(txt .c_str(),&tmp)) ;
cout << pNum << "\n"; //stick into pNum later

.........only to find in yours here --that I didn't even _need_ strod() !
(I thought his was elegant when I first saw it; I'm such a newbie....)

I compiled your code and ran it.
The numbers _are_ numbers, without strtod() !
I will study this thread intensely.
Is this sort of thing common?

_Thanks_! (many additional exclams)
What a great resource and learning aid you people are!
--
Peace
JB
jb@tetrahedrave rse.com
Web: http://tetrahedraverse.com

Jan 30 '08 #3

"Alf P. Steinbach" <al***@start.no wrote in message
news:13******** *****@corp.supe rnews.com...
* Boltar:
I'm using ifstream (which I hardly ever use) to read an ascii text
file (containing numbers delimited by newlines) in a loop using
something like:

ifstream infile("filenam e")
int value;

infile >value;
while(!infile.e of() {
infile >value;
:

}

The problem is if the file is missing a terminating newline the final
number is missed. How can I make sure its read anyway when the newline
is missing?

Don't test for eof, test for good stream state, i.e. that last read was
successful.

Like

ifstream infile( "filename" );

for( ;; )
{
int value;

infile >value;
if( !infile.good() )
{
break;
}
// Do something with value.
}
if( !infile.eof() ) { /* oops. */ }

Disclaimer: I really hate iostreams, so possibly that last check isn't
completely 100% cover-all-cases or guaranteed to detect failure.
May I please ask further?
I ran this, modified as follows:
(usual up-top-stuff)

int main() {
ifstream infile("file.ex t");
for(;;)
{
double value;
char toss; /*remove the commas (delimiter) & newlines*/
if(!infile.good ()) {break;}
cout<<value<<" ";
}
infile>>value; cout<<value; /*kludge does get the final number....*/
if (!infile.eof()) {/*oops*/} /*my kludge for oops...(?)*/
return 0;
}

.......and it, too, misses the last number in the file without the post-loop
single extra use of infile>>value.. ..
I tried many things, including the FAQ version, and putting an extra \n onto
the end of the file being read. No go; same problem.
All lines of file, example: 2.3,45.90,23,-0.2334,0.9\n
I get a beautiful sequence of every number in the file, exactly what I
wanted, and they are all _numbers_ (hallelujah), but the last one's not
there.

Your code modified to my need does everything I want it to except catch the
last number in the file _without_ the ugly kludge....

Is there more to this _neat_ clean way of getting my numbers from the file,
that catches the last one but also allows use of the char non-number
tosser?

Thanks!
--
Peace
JB
jb@tetrahedrave rse.com
Web: http://tetrahedraverse.com


Jan 30 '08 #4
On Jan 30, 11:47*am, "Alf P. Steinbach" <al...@start.no wrote:
* John Brawley:


"Alf P. Steinbach" <al...@start.no wrote in message
news:13******** *****@corp.supe rnews.com...
* Boltar:
I'm using ifstream (which I hardly ever use) to read an ascii text
file (containing numbers delimited by newlines) in a loop using
something like:
>ifstream infile("filenam e")
int value;
>infile >value;
while(!infile. eof() {
* * * *infile >value;
* * * *:
>}
>The problem is if the file is missing a terminating newline the final
number is missed. How can I make sure its read anyway when the newline
is missing?
Don't test for eof, test for good stream state, i.e. that last read was
successful.
Like
* *ifstream infile( "filename" );
* *for( ;; )
* *{
* * * *int value;
* * * *infile >value;
* * * *if( !infile.good() )
* * * *{
* * * * * *break;
* * * *}
* * * *// Do something with value.
* *}
* *if( !infile.eof() ) { /* oops. */ }
Disclaimer: I really hate iostreams, so possibly that last check isn't
completely 100% cover-all-cases or guaranteed to detect failure.
May I please ask further?
I ran this, modified as follows:
(usual up-top-stuff)
int main() {
ifstream infile("file.ex t");
for(;;)
* * {
double value;
char toss; */*remove the commas (delimiter) & newlines*/
if(!infile.good ()) {break;}
cout<<value<<" ";
* * }
infile>>value; cout<<value; */*kludge does get the final number....*/
if (!infile.eof()) {/*oops*/} */*my kludge for oops...(?)*/
return 0;
}
......and it, too, misses the last number in the file without the post-loop
single extra use of * infile>>value.. ..
I tried many things, including the FAQ version, and putting an extra \n onto
the end of the file being read. *No go; same problem.
All lines of file, example: 2.3,45.90,23,-0.2334,0.9\n
I get a beautiful sequence of every number in the file, exactly what I
wanted, and they are all _numbers_ (hallelujah), but the last one's not
there.

Try 'infile.fail()' or just '!infile' instead of '!infile.good() '.

As I wrote, I hate 'em streams and so couldn't guarantee correctness.
IMO the problem is that EOF is simultaneously a character in the
stream and some sort of abstraction representing the end of the
stream.

IIRC is.good() holds even if next op is is.get() == EOF;

is.good() is meant to be true if characters are available, but IMO if
the next char is EOF then by definition no characters are available.

Further if EOF is a character and you are at eof(), then you should
IMO be able to is.putback(), but IIRC you can't.

I opted to wrap up text streams, so they all have the same semantic,
for files, console and strings. Any stream has a name, for files the
name of the file, for strings a name you supply and for console the
name of the console ( and a terminator you supply) Also every stream
keeps a record of line and column position, so you can output error
messages including name, and current position in a user friendly
format. Final part is a checkpoint stack, so you can create
checkpoints with useful messages, and they pop off the stack at the
end of their scope. Another stream type is a stream stack, where you
can push and pop streams (say for #include files, or macros. Its not
perfect as ideally you should be able to pushback through eof, but
because of the semantics of std::stteams this isnt really feasible.

However I do despair of the std::streams ...

I expect I will hear other opinions from experts about the issue :-)

regards
Andy Little

Jan 30 '08 #5
In article <2db713c3-6d93-4f93-8fed-ee7a71ad52e5
@y5g2000hsf.goo glegroups.com>, an**@servocomm. freeserve.co.uk says...

[ ... ]
is.good() is meant to be true if characters are available, but IMO if
the next char is EOF then by definition no characters are available.
You're misinterpreting is.good(). It's meant to indicate the current
error state of the stream buffer. IOW, if the end of file has been
encountered, it should signal so -- but if it hasn't been encountered
yet, it should NOT signal so.

IMO, this is generally a good thing -- Pascal's I/O system worked as you
describe and it made writing correct loops considerably more difficult.
Further if EOF is a character and you are at eof(), then you should
IMO be able to is.putback(), but IIRC you can't.
Trivially true -- any statement of the form "if x then y' is true, but
meaningless if x if false. In this case, you start with the idea that
EOF is a character -- but since it's not, the rest of the statement
means nothing.
I opted to wrap up text streams, so they all have the same semantic,
for files, console and strings. Any stream has a name, for files the
name of the file, for strings a name you supply and for console the
name of the console ( and a terminator you supply) Also every stream
keeps a record of line and column position, so you can output error
messages including name, and current position in a user friendly
format. Final part is a checkpoint stack, so you can create
checkpoints with useful messages, and they pop off the stack at the
end of their scope. Another stream type is a stream stack, where you
can push and pop streams (say for #include files, or macros. Its not
perfect as ideally you should be able to pushback through eof, but
because of the semantics of std::stteams this isnt really feasible.
If you're wrapping the stream anyway, it's pretty trivial to add your
own capability to put things back, even when not supported by the stream
itself (just put whatever back into your own buffer, and have your input
routines check that buffer before reading from the stream).

Years ago, I wrote a wrapper for lexing C source code that wrapped C's
FILE * I/O. It allowed you to unget a more or less arbitrary amount of
data -- and unless memory serves me particularly badly today, it should
have still allowed you to unget (and read) data after the stream itself
had encountered EOF.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jan 31 '08 #6
On Feb 1, 4:07 pm, Jerry Coffin <jcof...@taeus. comwrote:
In article <28432abe-730f-4a4c-8ef1-311adfef3131
@b2g2000hsg.goo glegroups.com>, james.ka...@gma il.com says...
[ ... ]
I'd much rather write some sort of manipulator to
handle separators. Much more flexible, and much more accurate.
"Accurate" means it adheres more closely to some defined standard. In
this case, the only standard provided was his original description of
the file format, to which this adhered _perfectly_. As such, no higher
degree of accuracy is possible.
Accurate may not be the right word, but it didn't seem to me
that he wanted to have more than one comma handled as a single
separator. It looked more like he was dealing with a CSV
format.
Done correctly, for example, it wouldn't allow multiple
commas to be treated as a single separator.
This is a perfectly reasonable way of fulfilling that
requirement IF IT EXISTS. Claiming that it's more accurate is
simply a falsehood in this case. It's not really more flexible
either -- it simply fulfills a different set of requirements.
The general approach is more flexible, in that it allows for a
greater degree of variation in defining your separators (and
signaling an error if a separator isn't conform).
On one hand, if you want a series of separators to be
translated as a series of empty fields, it fulfills that
requirement quite nicely. OTOH, it makes it much more
difficult to meet a requirement that an arbitrary number
separators can be used to separate any two fields.
It's pretty trivial to add a loop on the comma.
Your solution would be extremely good if it was required --
but at least according to the OP, no such requirement exists.
That wasn't the way I interpreted what he said, but of course,
he didn't present an exact specification. In the end, it
probablyl depends on the wording in the specification: if the
specification says that commas are to be treated as white space,
then a new locale is a reasonable solution; if the specification
defines separators, then I think a manipulator which eats
separators is more appropriate. (I also think that a beginner
will reach the level of being able to write such manipulators
much sooner than being able to write a new locale. I know that
I have problems went I need to implement a new locale, and I'm
hardly a beginner.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 1 '08 #7
On Feb 1, 2:05 pm, "Alf P. Steinbach" <al...@start.no wrote:
* James Kanze:
[...]
I just refuse to go around remembering arcane details of iostreams.
They're that ugly. :-)
The naming conventions and the error handling are bad, I'll
grant you that. And of course, IF you use the "standard" idiom,
you don't have to remember them.

[...]
The most important reason to use it is because it is the
standard idiom.
[...]
(even if in this case, it's a bit longer.) But that's not the
issue here. I don't write it like that, however, because as I
said above---any time you see something other than what is in
the FAQ...
Let's not elevate the FAQ to infallible authority.
Both you and I have contributed to the FAQ (at least I think
you have, I know I have).
If it were only the FAQ, and other experts in iostream were
saying other things... But all of the people I know who are
really competent in iostream use the same idiom.
So saying our own statements and viewpoints etc. are godlike
authoritative just because they have ended up in the FAQ, it
would be a very circular argument :-), and besides, in
addition to much great advice, the FAQ also contains some
dubious statements and examples.
I know. (As it happened, this idiom predates the time I learned
C++, so I can't claim any responsibility for it.)
Most experienced programmers, on seeing such code,
would start by asking if I understood iostream, or if he knew
better, by asking what was special here that caused me to break
with the standard idiom.
Some idioms are good.
Some are not.
More precisely: the fact that something is an established idiom
is a positive point for it. Other, negative points, can
outweigh that. In this case, although I'd have done something
different if the idiom didn't exist, the bad points of the idiom
are small enough that they don't outweigh the advantage of using
the idiom.

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

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

Similar topics

7
3226
by: Anton Ishmurzin | last post by:
Greetings All, I think everybodyknows the answer already. But i am quite a newbie in c++. I've got the following line in my code: ifstream ini_file_in("filename.dat", ios::in); But, the gcc (GCC) 3.2 spits out some stuff about
6
3378
by: Ram Laxman | last post by:
Iam new bie to C++ programming.. I want to write a program which will read the Comma separated values(CSV) file column wise. For example: In a.txt: "TicketNumber","Phone","CarNumber" 10,20,30
4
2851
by: Gunnar | last post by:
Hello. The (stupid) code below does not compile with the message In method `istream::istream(const istream &)': /usr/lib/gcc-lib/i386-linux/2.95.4/../../../../include/g++-3/streambuf.h:128: `ios::ios(const ios &)' is private Silly.cpp:15: within this context It's the function call to "foo" that does not work. My question is, what is
15
2807
by: Christopher Benson-Manica | last post by:
The dumb-o-meter's pegging out today... What, if anything, is wrong with the following code? std::ifstream f( "myfile.txt" ); if( !f ) { cerr << "Couldn't open file\n"; } while( getline(f,s) ) { cout << s << '\n'; }
4
3726
by: hall | last post by:
Hi. I ran across a bug in one of my problems and after spending some time tracking it down i found that the problem arose in a piece of code that essentially did this: ----------- ifstream in("in.txt"); if(!in) {cout << "error\n";} in.close(); if(!in) {cout << "error\n";} in.close(); if(!in) {cout <<...
2
2218
by: Mathieu Malaterre | last post by:
Hi, I am tryig to convert part of a c++ IO library. Right now I am removing all 'FILE*' and replace them with ifstream. But I have a problem, after seeking through a stream I have to call the ijg (jpeg library). Since this is a C library it uses FILE*. My question is then is there a compatibility layer for ifstream <-> FILE* ? It should...
1
6236
by: inkapyrite | last post by:
Hi all. I'm using ifstream to read from a named pipe but i've encountered an annoying problem. For some reason, the program blocks on reading an ifstream's internal buffer that's only half-filled. Only when the buffer becomes full does it resume execution. Here's my test code for reading from a pipe: //(compiled with g++ -std=c++98)...
2
14027
by: Karl | last post by:
Hey everyone! I've got a quick question on whether std::ifstream is buffered or not. The reason is that I have a homework assignment that requires me to benchmark copying files using different buffer sizes. I ended up doing this using std::istream::readsome() and std::ostream::write(): // now try writing to the destination file...
4
4737
by: manontheedge | last post by:
i'm working on a C++ program that uses operator overloads (which i'm just learning to use), and i have the ostream working fine, but i'm thinking i'm using it wrong somehow because the ofstream doesn't work. Here's some code fragments... class matrix { public: ...... friend ostream& operator << ( ostream& os, matrix& m );
0
7698
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
1
7673
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7970
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6284
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5219
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3640
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2113
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 we have to send another system
0
937
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.