IO problem

N

nvangogh

I have come to a question in C++ Primer (p 314 , exercise 8.1) that is
not clear to me.
"Write a function that takes and returns an istream&. The function
should read the stream until it hits end-of-file. The function should
print what it reads to the standard output. Reset the stream so that it
is valid before returning the stream."

Breaking this down, the function has to do three things:

1. Read a stream until it hits end-of-file
So the >> operator reads input from an istream object - cin.
This stream's end of file can be interrogated by
cin.eof(). This returns true if the end of file bit is set which can be
tested with a bool variable
bool on = false;
on = cin.eof();
if(on == true)
// end of file is reached, else
if(on ==false)
// keep reading cin

I don't believe that this is completely correct so can someone show me
how this code should be presented?

2. Print what is read to the standard output
I can only imagine this to be cout << ? But am lost from here

3. Reset the stream so it is valid before returning the stream
This section of the problem again defeats me.

Can anyone help with this function?
 
V

Victor Bazarov

I have come to a question in C++ Primer (p 314 , exercise 8.1) that is
not clear to me.
"Write a function that takes and returns an istream&. The function
should read the stream until it hits end-of-file. The function should
print what it reads to the standard output. Reset the stream so that it
is valid before returning the stream."

Breaking this down, the function has to do three things:

1. Read a stream until it hits end-of-file
So the >> operator reads input from an istream object - cin.
This stream's end of file can be interrogated by
cin.eof(). This returns true if the end of file bit is set which can be
tested with a bool variable
bool on = false;
on = cin.eof();
if(on == true)
// end of file is reached, else
if(on ==false)
// keep reading cin

I don't believe that this is completely correct so can someone show me
how this code should be presented?

There has to be something after the 'if' and its condition to designate
the action that shall be taken when the condition is met. So, instead
of the comments ("// end of file is reached") put something there so
that the program takes the action you want it to take. Same for the
other condition.

Usually, if you only have a "either-or" situation (like in your case,
it's either the end of file or not), then there is no need for the
second 'if', a simple 'else' ought to do. Something *like*

if (on)
...
else
...

(put the proper action instead of the ellipsis)
2. Print what is read to the standard output
I can only imagine this to be cout << ? But am lost from here

Yes, that's pretty much what you need to do.
3. Reset the stream so it is valid before returning the stream
This section of the problem again defeats me.

std::cin.clear();

resets the error condition on the 'std::cin' stream.
Can anyone help with this function?

Part of the answer can also be found in the FAQ, section 5, question 2,
if memory serves.

V
 
B

Barry Schwarz

There are at least a couple of responses in comp.lang.c++.moderated.
Please don't multipost.
 
J

James Kanze

I have come to a question in C++ Primer (p 314 , exercise 8.1) that is
not clear to me.
"Write a function that takes and returns an istream&. The function
should read the stream until it hits end-of-file. The function should
print what it reads to the standard output. Reset the stream so that it
is valid before returning the stream."

This doesn't sound to clear to me either. For the most part,
istream input is formatted, so a lot of the characters don't
appear. I'm not too sure what you're supposed to be reading.
If it's ints, for example:

int i;
while ( file >> i && ! file.eof() ) {
if ( ! file ) {
file.clear();
file.ignore(); // but what, and how far?
} else {
std::cout << i << std::endl;
}
}

But of course, this will not reproduce the white space of the
original file. Otherwise:

std::cout << file.rdbuf();

sounds like the complete solution to the problem (but it's not
the sort of answer I'd expect from an introductory text).
Breaking this down, the function has to do three things:
1. Read a stream until it hits end-of-file

Which is already a bit questionable. Normally, you read until
the read fails. Which can be because of end-of-file, but can
also be for other reasons.
So the >> operator reads input from an istream object - cin.
This stream's end of file can be interrogated by
cin.eof().

Not really. The eof function is a bit tricky, in that its
return value reflects, or can reflect, internal state which
isn't well defined. Generally, you would never use cin.eof()
until input had failed.
This returns true if the end of file bit is set which can be
tested with a bool variable
bool on = false;
on = cin.eof();
if(on == true)
// end of file is reached, else
if(on ==false)
// keep reading cin
I don't believe that this is completely correct so can someone show me
how this code should be presented?

It's not completely correct, or at least, it's not complete.
cin.eof() does return the status of the eofbit. But when the
eofbit is set depends on a number of things, and it isn't
reliable unless an input has failed (and not always then).

The usual idiom is:

while ( std::cin >> something ) // ...

or (for lines):

while ( std::getline( std::cin, line ) // ...

(where line has type std::string).

After failure, you can use std::cin.eof() to determine whether
the failure is due to end of file, or something else. (In the
case of std::getline, it will almost certainly be end of file.)
2. Print what is read to the standard output
I can only imagine this to be cout << ? But am lost from here

std::cout << will do the trick. But in the two while loops
above, the >> operator or getline will have removed characters
(white space or the new line character )from the input, that you
won't ever see.

The one exception is << from a streambuf. Using it is the
idiomatic way of copying one stream to another in C++. But it
represents a special case, which violates most of the usual
rules.
3. Reset the stream so it is valid before returning the stream
This section of the problem again defeats me.

Again, it's not clear what this is supposed to mean. If the
input stream is a file (e.g. std::cin), there's practically no
way of doing this. std::cin.clear() will set the state to
good(), but since you've seen end of file, the next read will
immediately fail (or not, depending on the
implementation---there's a lot which isn't well defined here).
Or... it may mean you have to rewind (seek to the beginning of
the file). But this won't be possible if the input is from a
keyboard. And of course, if you've used std::cout <<
file.rdbuf(), the input stream won't have seen anything, and
will still be in its orginal state (but trying to read from it
will still fail, because the underlying streambuf is at end of
file).
 

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

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top