473,386 Members | 1,810 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.

ifstream getline() problem

Hello all,

I am trying to read in lines into a buffer from a file. Normally I would do
this very low-level,
but I have come to the conclusion I must stop doing everything the hard way.
So, I thought I would try
<fstream>. The code below causes an infinite loop in the while() statement.
Debugging, I see that the buffer just has a 0 in
the first position, and nothing else.

ifstream listfile;

listfile.open("data\\modellist.txt", ios::in);

if(listfile.bad()) return 0;

char buffer[100];

while(!listfile.getline(buffer, 100).eof())

{

//Do stuff with buffer

}

Anyone know why? The file is ok, and works fine with fread and the like.

Thanks in advance!
Jul 19 '05 #1
11 37865
"John" <jo**@ivide.com> wrote in message news:3f0e780e@shknews01...
| I am trying to read in lines into a buffer from a file. Normally I would
do
| this very low-level,
| but I have come to the conclusion I must stop doing everything the hard
way.
| So, I thought I would try
| <fstream>. The code below causes an infinite loop in the while()
statement.
| Debugging, I see that the buffer just has a 0 in
| the first position, and nothing else.
....
| ifstream listfile;

Note that the easiest way to do things safely and correctly is:
std::string line;
while( std::getline( listfile, line ) )
{ ... }

| char buffer[100];
|
| while(!listfile.getline(buffer, 100).eof())

If getline() fails for any other reason than eof, this will
get into an infinite loop. Also, the last non-empty but valid
line could be neglected (IIRC, eof is set if the line was
extracted successfully up to the end of the file instead
of a newline).

A better test for the exit condition would be:
while( !listfile.getline(buffer, 100).fail() )
or simply (relying on a cast operator):
while( listfile.getline(buffer, 100) )
or my personally preferred style:
while( !! listfile.getline(buffer, 100) )

hth,
--
Ivan Vecerina, Dr. med. <> http://www.post1.com/~ivec
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #2
Ivan Vecerina wrote:
or my personally preferred style:
while( !! listfile.getline(buffer, 100) )


What's the difference between that and

while (listfile.getline(buffer, 100))

? Why the need for the double '!'?

--
"Codito ergo sum"
Roel Schroeven
Jul 19 '05 #3
John wrote:
Hello all,

I am trying to read in lines into a buffer from a file. Normally I would do
this very low-level,
but I have come to the conclusion I must stop doing everything the hard way.
So, I thought I would try
<fstream>. The code below causes an infinite loop in the while() statement.
Debugging, I see that the buffer just has a 0 in
the first position, and nothing else.

ifstream listfile;

listfile.open("data\\modellist.txt", ios::in);

if(listfile.bad()) return 0;

char buffer[100];

while(!listfile.getline(buffer, 100).eof())

{

//Do stuff with buffer

}
Try

std::ifstream listfile (filename, std::ios_base::in);

if (stream)
{
std::string s;
while (std::getline (listfile, s))
{
// do stuff
}
}

Are you running from the right directory?

Anyone know why? The file is ok, and works fine with fread and the like.

bad () is not the opposite of good ().

Thanks in advance!


Jul 19 '05 #4
John wrote:
I changed it to your suggestion:

string line;

while(getline(listfile, line))

{ }

But now it does not even enter the loop at all. So, something must be wrong
with the file stream, but
listfile.bad() doesn't show this.
The 'ios_base::badbit' state flag usually indicates some sort of unusual
malfunction -- e.g., a sector on the floppy disk is bad (cannot be read)
and so the OS aborted the read attempt. IOW, you shouldn't use the
..bad() member function to detect "normal" I/O failures (e.g., end of
file, unexpected data value, etc.).
Is there anything obvious that I have
missed? The code can be broken down to:
ifstream listfile("data\\modellist.txt");

getline(listfile, line) //line is a std::string

and this compiles, but does not work. What am I missing? Is there a way to
actually find out what failed?


Consider the following code sample.

<example>

<code>
#include <iostream>
#include <sstream>

class show_iostate {
protected:
std::ios_base::iostate state_;
public:
show_iostate (std::ios & stream) : state_(stream.rdstate()) { }
virtual ~show_iostate () { }
virtual std::ostream & print (std::ostream &) const;
};

std::ostream &
show_iostate:: print (std::ostream & out) const
{
out
<< (std::ios_base::badbit & state_ ? 'B' : '-')
<< (std::ios_base::eofbit & state_ ? 'E' : '-')
<< (std::ios_base::failbit & state_ ? 'F' : '-')
<< (std::ios_base::goodbit == state_ ? 'G' : '-')
;
return out;
}

std::ostream &
operator << (std::ostream & out, const show_iostate & s)
{
return s.print(out);
}

int main()
{
std::string s;
std::istringstream iss("Hello\nworld!");
std::cout << "Before : " << show_iostate(iss) << '\n';
while ( std::getline(iss, s) ) {
std::cout << "Loop : " << show_iostate(iss)
<< " [" << s << "]\n";
}
std::cout << "After : " << show_iostate(iss) << '\n';
}
</code>

<output>
Before : ---G
Loop : ---G [Hello]
Loop : -E-- [world!]
After : -EF-
</output>

</example>
For debugging purposes you could write,

ifstream listfile("data\\modellist.txt");
std::cout << "listfile : " << show_iostate(listfile) << '\n';

This would show the 'listfile' object's iostate status after the file
open attempt is made. If listfile's status is displayed as '---G' (i.e.,
listfile's iostate is "ios::goodbit"), then the open attempt was
successful and you can turn your attention to the getline() call, and so on.

--
Jim

To reply by email, remove "link" and change "now.here" to "yahoo"
jfischer_link5809{at}now.here.com
Jul 19 '05 #5
> Try

std::ifstream listfile (filename, std::ios_base::in);

if (stream)
{
std::string s;
while (std::getline (listfile, s))
{
// do stuff
}
}

Are you running from the right directory?

Anyone know why? The file is ok, and works fine with fread and the like.


bad () is not the opposite of good ().


What is stream? Do you mean if(listfile) or if (listfile.is_open()) ?
Jul 19 '05 #6
"Roel Schroeven" <j4*******@sneakemail.com> wrote in message
news:kx***************@afrodite.telenet-ops.be...
Ivan Vecerina wrote:
or my personally preferred style:
while( !! listfile.getline(buffer, 100) )


What's the difference between that and

while (listfile.getline(buffer, 100))


In this case, there is no actual difference.
But the latter line relies on an *implicit* conversion
to bool. Actually, if you look into it, this is not just
a conversion to bool, but a conversion to void* -- that's
because there are some tricky issues related to such an
implicit conversion operator, so the standard library
provides the latter conversion to mimic a bool() operator.

Even as it is, one could still get in trouble:
void Verify(bool testThatMustBeTrue);
void Verify(void* pointerThatMustBeValid);
If you were to write:
Verify( listfile.getline(buffer,100) );
It is the second overload of Verify that would be called.
(and the non-zero pointer that is returned by the void*
conversion could be some invalid or illegal address ).

These implicit conversion issues do not apply when
using the operator !() overloaded by the stream classes
(which returns a bool, but with the opposite logical value).
Now, as I said, using the " !! " operator is a
style convention. I have adopted it since I've seen
it used a couple years ago, and never needed to go back.
(though, as for other style issues, I remain flexible).
Because implicit conversions to bool have some caveats,
you will see that several coding standards require
the use of:
if( myPtr != NULL ) and if( myPtr == NULL )
instead of:
if( myPtr ) and if( ! myPtr )
To avoid a common mistake: if( myPtr = NULL )
some even advise the following style:
if( NULL != myPtr ) and if( NULL == myPtr )
Instead of that, I just like the symmetry
and simplicity of writing:
if( !! myPtr ) and if( ! myPtr )
In all circumstances I know, " !! " can be considered
and used as a built-in "convert-to-bool" operator.
It also works nicely with stream-classes and the like
that provide a conversion to bool to check validity.
And in our own classes, when a similar validity test
is needed, we only provide an operator!(), and do not
mess with implicit conversion operators.
So it is just a style convention we adopted,
and we think it has real benefits compared to
other approaches.
Best regards,
--
Ivan Vecerina, Dr. med. <> http://www.post1.com/~ivec
Soft Dev Manager, XiTact <> http://www.xitact.com
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #7
Ivan Vecerina wrote:
"Roel Schroeven" <j4*******@sneakemail.com> wrote in message
news:kx***************@afrodite.telenet-ops.be...
Ivan Vecerina wrote:
> or my personally preferred style:
> while( !! listfile.getline(buffer, 100) )
What's the difference between that and

while (listfile.getline(buffer, 100))


[...]
In all circumstances I know, " !! " can be considered
and used as a built-in "convert-to-bool" operator.
It also works nicely with stream-classes and the like
that provide a conversion to bool to check validity.

So it is just a style convention we adopted,
and we think it has real benefits compared to
other approaches.


Thanks for the elaborate explanation. I've used !! myself in the past
for converting from int to bool, not knowing it is actually recommended
practice.

--
"Codito ergo sum"
Roel Schroeven
Jul 19 '05 #8
"Roel Schroeven" <j4*******@sneakemail.com> wrote in message
news:Ib****************@afrodite.telenet-ops.be...
Ivan Vecerina wrote:
In all circumstances I know, " !! " can be considered
and used as a built-in "convert-to-bool" operator.
It also works nicely with stream-classes and the like
that provide a conversion to bool to check validity.

So it is just a style convention we adopted,
and we think it has real benefits compared to
other approaches.


Thanks for the elaborate explanation. I've used !! myself in the past
for converting from int to bool, not knowing it is actually recommended
practice.


I wouldn't dare call !! "recommended practice" just because I
like and recommend its use ;)
(when I say 'we', I just speak for myself and the team
I work with on various development projects).

I haven't invented the approach, but I have found it to be
convenient, and haven't seen a situation yet where it
creates problems.

Maybe someone here will voice a different opinion...
Cheers,
Ivan
--
Ivan Vecerina, Dr. med. <> http://www.post1.com/~ivec
Soft Dev Manager, XiTact <> http://www.xitact.com
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #9

Ivan Vecerina wrote:

"Roel Schroeven" <j4*******@sneakemail.com> wrote in message
news:Ib****************@afrodite.telenet-ops.be...
Ivan Vecerina wrote:
In all circumstances I know, " !! " can be considered
and used as a built-in "convert-to-bool" operator.
It also works nicely with stream-classes and the like
that provide a conversion to bool to check validity.

So it is just a style convention we adopted,
and we think it has real benefits compared to
other approaches.


Thanks for the elaborate explanation. I've used !! myself in the past
for converting from int to bool, not knowing it is actually recommended
practice.


I wouldn't dare call !! "recommended practice" just because I
like and recommend its use ;)
(when I say 'we', I just speak for myself and the team
I work with on various development projects).

I haven't invented the approach, but I have found it to be
convenient, and haven't seen a situation yet where it
creates problems.

Maybe someone here will voice a different opinion...


"!!" sucks. http://google.com/groups?selm=3E271E...AA6BB%40web.de

regards,
alexander.
Jul 19 '05 #10
Duane Hebert wrote:
Try

std::ifstream listfile (filename, std::ios_base::in);

if (stream)
{
std::string s;
while (std::getline (listfile, s))
{
// do stuff
}
}

Are you running from the right directory?

Anyone know why? The file is ok, and works fine with fread and the like.


bad () is not the opposite of good ().

What is stream? Do you mean if(listfile) or if (listfile.is_open()) ?


Ah, yes. Thanks. I meant `if (listfile)'.

Jul 19 '05 #11
Lot's of good samples here, with some good explanations. I don't know if you're still looking at this, I've had similar problems before. I always use the following code after spending too much time within the std:: namespace looking at what was different between <iostream> and <iostream.h>
...

std::ifstream listfile (filename, std::ios_base::in);
std::string line;

while(!listfile.eof() && !listfile.fail()) {
std::getline(listfile, line);
if(!line.empty()) {
// do stuff
}
}

It may seem like a few extra lines of code to all you linefreaks out there but it always work, without exception, and everyone who looks at it again after you've moved on immediately sees what it is doing without wasting time thinking about it. :D

If you really want to be overly verbose you can add an if(listfile.fail()) before the if(!line.empty()) and figure out what failed and why, sometimes you can clear the fail bit, read in the next line and proceed as normal.

Hope this helps, cheerio and all that...
Cliff Kilpatrick
Oct 4 '05 #12

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

Similar topics

4
by: Joe | last post by:
Hello - I wrote a program that uses ifstream to open an ASCII file and getline() to read in the lines. The problem is when I try to open the same file again later in the code. I used close()...
1
by: Jim Phelps | last post by:
Hello all, I am in a bit of a pickle using the getline function with an ifstream. It does not seem to work as advertised. Here is my scenario. In a nutshell, my code needs to pick up a fixed...
6
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"...
6
by: csvka | last post by:
Hello, I wonder if I could pick your brains. I'm beginning to learn about C++. I have opened a file in my program and I want to read lines from it. I would like this to be done in a separate...
1
by: tinks | last post by:
I am getting a linking error when I do something like this: ifstream dataFile; dataFile.open(dataFileName_, ios::in); while(dataFile) { dataFile.getline(buffer, MAX_DATA_FILE_LINE_LEN); //...
6
by: Dave | last post by:
In .Net 2003 if a line, read from a text file is larger than a size parameter, the ifstream getline(buff, sze) put the file pointer to the EOF, so next peek() returns EOF. I saw this problem...
2
by: Assertor | last post by:
Hi, All. (VC++6.0) I found some strange thins when using getline() and seekg() of std::ifstream. After the file position of an open file was shift to the end of the file, seekg() did not...
2
by: manwanirg | last post by:
the function getline is a public member of istream and cin.getline can be used. Since ifstream is publicily derived from istream, getline shall be available in ifstream as well. However,on solaris...
3
by: toton | last post by:
Hi, I want to unread a few things while I am reading a file. One solution I know is putback the characters read to the buffer. But as I need frequent moving file pointer , to a few steps back, I...
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
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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,...
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
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...

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.