Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > ifstream getline() problem

Reply
Thread Tools

ifstream getline() problem

 
 
John
Guest
Posts: n/a
 
      07-11-2003
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!


 
Reply With Quote
 
 
 
 
Ivan Vecerina
Guest
Posts: n/a
 
      07-11-2003
"John" <(E-Mail Removed)> 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


 
Reply With Quote
 
 
 
 
Roel Schroeven
Guest
Posts: n/a
 
      07-11-2003
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
 
Reply With Quote
 
Buster Copley
Guest
Posts: n/a
 
      07-11-2003
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!
>
>


 
Reply With Quote
 
Jim Fischer
Guest
Posts: n/a
 
      07-11-2003
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:stream & print (std:stream &) const;
};

std:stream &
show_iostate:: print (std:stream & 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:stream &
operator << (std:stream & 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


 
Reply With Quote
 
Duane Hebert
Guest
Posts: n/a
 
      07-11-2003
> 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()) ?


 
Reply With Quote
 
Ivan Vecerina
Guest
Posts: n/a
 
      07-12-2003
"Roel Schroeven" <(E-Mail Removed)> wrote in message
news:kxwPa.368$(E-Mail Removed)-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


 
Reply With Quote
 
Roel Schroeven
Guest
Posts: n/a
 
      07-12-2003
Ivan Vecerina wrote:
> "Roel Schroeven" <(E-Mail Removed)> wrote in message
> news:kxwPa.368$(E-Mail Removed)-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
 
Reply With Quote
 
Ivan Vecerina
Guest
Posts: n/a
 
      07-12-2003
"Roel Schroeven" <(E-Mail Removed)> wrote in message
news:Ib_Pa.3799$(E-Mail Removed)-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


 
Reply With Quote
 
Alexander Terekhov
Guest
Posts: n/a
 
      07-12-2003

Ivan Vecerina wrote:
>
> "Roel Schroeven" <(E-Mail Removed)> wrote in message
> news:Ib_Pa.3799$(E-Mail Removed)-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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ifstream getline() Problem ... Joe C++ 4 01-22-2004 03:31 PM
Problem opening ifstream twice ... Joe C++ 2 01-20-2004 03:22 PM
Problem with ifstream Alexandros C++ 0 12-26-2003 12:31 PM
ifstream on gcc 3.2 problem, simple question Anton Ishmurzin C++ 7 11-26-2003 01:34 PM
ifstream - read - problem Nils Wogatzky C++ 5 09-08-2003 09:14 PM



Advertisments