.Net 2003 ifstream getline(buff, sze) jumps to EOF if line>size

D

Dave

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 also when size was 2000 but line was
1200 bytes long.
There is no such problem with .Net 2002
For .Net 2003 I used :
#include <string>
#include <fstream>
using namespace std;

The same function in .Net 2002 works fine.
Thanks,
Dave
 
D

David Lowndes

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 also when size was 2000 but line was
1200 bytes long.
There is no such problem with .Net 2002
The same function in .Net 2002 works fine.

Dave,

Do you have a simple example (and a simple file that illustrates the
difference)?

I think I can reproduce what you're seeing, but I get consistent
results with VS2003 & VC6 (I don't have VS2002 installed to check what
it does).

Here's the code I've tried if you want to check how this behaves for
you with VS2002 & VS2003:

#include <string>
#include <fstream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
ifstream is;

is.open( argv[1], ios_base::in );

char buffer[10];

is.getline( buffer, 5 );

int ret = is.peek();
if ( char_traits<char>::eof() == ret )
{
cout << "EOF returned";
}
else
{
cout << "Not EOF";
}

is.close();

return 0;
}


and the sample file is a text file containing:

12345678901234567890
987654321

After calling getline, the buffer contains "1234" (and a null
character), and the following call to peek always (it seems incorrect
to me) returns eof.

Stepping through the code, it appears that peek fails because the
getline method sets the state of the stream to a failure case because
the buffer end is reached. Skipping past this check does return the
next character in the file, so the file pointer would appear to be
correct.

I don't usually use with these stream methods, so I'm not sure what
the expected behaviour should be.

Dave Lowndes
 
T

tom_usenet

12345678901234567890
987654321

After calling getline, the buffer contains "1234" (and a null
character), and the following call to peek always (it seems incorrect
to me) returns eof.

Once a stream is in an error state, (almost) all functions will fail.
To reset the error state, call "stream.reset()".

int_type peek();
27 Returns: traits::eof() if good() is false. Otherwise, returns
rdbuf()­>sgetc().

That's clear enough - after trying to read a line into a buffer that
is too small, the "fail" bit of the stream is set (note that eof()
will return false still though, since eof hasn't been hit). With the
fail bit set, good() is false and hence peek() returns EOF.
Stepping through the code, it appears that peek fails because the
getline method sets the state of the stream to a failure case because
the buffer end is reached. Skipping past this check does return the
next character in the file, so the file pointer would appear to be
correct.

I don't usually use with these stream methods, so I'm not sure what
the expected behaviour should be.

The behaviour is correct. The standard library has been tested with
several different proofing tools and is therefore unlikely to contain
such trivial bugs.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 
D

David Lowndes

Once a stream is in an error state, (almost) all functions will fail.

That's reasonable, I guess the issue is should using getline in that
manner put the stream into an error state? I think that's perhaps the
counter-intuitive aspect - though it's (sort of) documented to do that
in the latest docs:

"If the function extracts no elements or _Count - 1 elements, it calls
setstate(failbit)"
To reset the error state, call "stream.reset()".

Err, how?

Aha, it seems to be called the clear() method.
The behaviour is correct. The standard library has been tested with
several different proofing tools and is therefore unlikely to contain
such trivial bugs.

Perhaps it should be tested on users though - to see what percentage
of real programmers find it intuitive/straightforward to use. I
suspect that's a much harder test, and one that I think much of STL
and its documentation will fail miserably at. :)

Dave
 
D

David Lowndes

Aha, it seems to be called the clear() method.

I should have mentioned before I got carried away, calling clear()
does resolve the issue.

Dave
 
H

Hendrik Schober

Dave said:
[problems with 'getline(buff, sze)']

Did you have a look at
std::istream& std::getline(std::istream&,std::string&)
generally, it is a lot easier to use.
Thanks,
Dave

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
 
S

Sean Kelly

David said:
That's reasonable, I guess the issue is should using getline in that
manner put the stream into an error state? I think that's perhaps the
counter-intuitive aspect - though it's (sort of) documented to do that
in the latest docs:

"If the function extracts no elements or _Count - 1 elements, it calls
setstate(failbit)" ....

Perhaps it should be tested on users though - to see what percentage
of real programmers find it intuitive/straightforward to use. I
suspect that's a much harder test, and one that I think much of STL
and its documentation will fail miserably at. :)

I think the important distinction is that you're calling getline and not
get. The point of getline is to read a line of data (ending with the
terminating char) into a buffer. In your example the full line would
not fit into the buffer so the operation was considered to have failed,
ie. getline basically requires that the delim be seen before count is
reached in order to succeed. If it seems counter-intuitive I'd argue
that it's because the MSDN docs aren't clear enough on what the function
is supposed to accomplish.
Perhaps it should be tested on users though - to see what percentage
of real programmers find it intuitive/straightforward to use. I
suspect that's a much harder test, and one that I think much of STL
and its documentation will fail miserably at. :)

It's probably a lot to expect from the average programmer, but this is
exactly the reason I keep a copy of the standard handy. When other docs
are unclear I still have an authoratative source to turn to.


Sean
 

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

Top