Reading a file using istearm

T

tushar.saxena

Hi,

I'm trying to read a file using the istearm class (I cant use ifstream
since the input might be a file or it might be stdin).


istream *input;
// Add checks for file name here, else use input = &cin;

while (!input->eof())
{
char readbuffer[32];
input->getline(readbuffer,32);
// Do something here
}

My problem here is this :

If the line contains less than 32 characters, this works fine and
reads the whole line

However if the line contains more than 32 characters,
i. readbuffer[] contains the first 31 characters of the stream ----
ii. gcount() returns 31 ----> Good
iii. tellg() returns -1 ----> Not good

As a result of the tellg() function returning -1, subsequent
readline() calls are reading from position -1 from the file and as
such the readline() fails.

My Question :

How can I work around this ?

One possible solution I could think of is maintain a count of the
number of characters read and manually do a seekg() to that position
before every read. However this doesn't sound like a very elegant
solution and not very efficient at all.

Also, is it possible to read an entire line of a file into a string
(or maybe a stringstream?) ? Irresepctive of the the line in the input
stream.

Thx !

- Tushar

(Disclaimer : I know a buffer size of 32 is small and likely to be
inefficient due to the numerous file accesses, but I chose it for
debugging so I can see whats going wrong)
 
K

kasthurirangan.balaji

Hi,

I'm trying to read a file using the istearm class (I cant use ifstream
since the input might be a file or it might be stdin).

istream *input;
// Add checks for file name here, else use input = &cin;

while (!input->eof())
{
char readbuffer[32];
input->getline(readbuffer,32);
// Do something here

}

std::string buf("");
while(getline(input,buf))
{
//do proessing, if any
}

this getline is provided by string. do not forget to include said:
My problem here is this :

If the line contains less than 32 characters, this works fine and
reads the whole line

However if the line contains more than 32 characters,
i. readbuffer[] contains the first 31 characters of the stream ----> Good

ii. gcount() returns 31 ----> Good
iii. tellg() returns -1 ----> Not good

As a result of the tellg() function returning -1, subsequent
readline() calls are reading from position -1 from the file and as
such the readline() fails.

My Question :

How can I work around this ?

One possible solution I could think of is maintain a count of the
number of characters read and manually do a seekg() to that position
before every read. However this doesn't sound like a very elegant
solution and not very efficient at all.

Also, is it possible to read an entire line of a file into a string
(or maybe a stringstream?) ? Irresepctive of the the line in the input
stream.

Thx !

- Tushar

(Disclaimer : I know a buffer size of 32 is small and likely to be
inefficient due to the numerous file accesses, but I chose it for
debugging so I can see whats going wrong)

Thanks,
Balaji.
 
T

tushar.saxena

Works like a charm. Thx !

I'm trying to read a file using the istearm class (I cant use ifstream
since the input might be a file or it might be stdin).
istream *input;
// Add checks for file name here, else use input = &cin;
while (!input->eof())
{
char readbuffer[32];
input->getline(readbuffer,32);
// Do something here

std::string buf("");
while(getline(input,buf))
{
//do proessing, if any

}

this getline is provided by string. do not forget to include <string>.
hope this works.




My problem here is this :
If the line contains less than 32 characters, this works fine and
reads the whole line
However if the line contains more than 32 characters,
i. readbuffer[] contains the first 31 characters of the stream ----> Good
ii. gcount() returns 31 ----> Good
iii. tellg() returns -1 ----> Not good
As a result of the tellg() function returning -1, subsequent
readline() calls are reading from position -1 from the file and as
such the readline() fails.
My Question :
How can I work around this ?
One possible solution I could think of is maintain a count of the
number of characters read and manually do a seekg() to that position
before every read. However this doesn't sound like a very elegant
solution and not very efficient at all.
Also, is it possible to read an entire line of a file into a string
(or maybe a stringstream?) ? Irresepctive of the the line in the input
stream.
(Disclaimer : I know a buffer size of 32 is small and likely to be
inefficient due to the numerous file accesses, but I chose it for
debugging so I can see whats going wrong)

Thanks,
Balaji.
 
R

Richard Herring

In message

It's also worth pointing out that this is almost never the right thing
to do. eof() doesn't become true until *after* you have tried (and
failed) to read beyond the end of the file.
{
char readbuffer[32];
input->getline(readbuffer,32);
// Do something here

}

This is the correct way: note that the test for failure takes place
*after* the call of getline().
std::string buf("");
while(getline(input,buf))
{
//do proessing, if any
}

this getline is provided by string. do not forget to include <string>.
hope this works.

[snip]
 
J

James Kanze

In message
(e-mail address removed) writes
It's also worth pointing out that this is almost never the
right thing to do. eof() doesn't become true until *after* you
have tried (and failed) to read beyond the end of the file.

Actually, whether it becomes true or not depends. You can't
count on it one way or the other.
{
char readbuffer[32];
input->getline(readbuffer,32);
// Do something here
}
This is the correct way: note that the test for failure takes
place *after* the call of getline().

And it doesn't involve calling eof().

Note too that in his original code: getline() sets failbit if it
cannot read a line, because the buffer is too small. (This
shouldn't be a problem with the version using std::string,
although in extreme cases, you may get a bad_alloc exception
from it.) And error status is sticky; the error remains (and
all further operations are no-ops) until it is explicitly
cleared.
 

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

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top