IO problem

Discussion in 'C++' started by nvangogh, Feb 19, 2014.

  1. nvangogh

    nvangogh Guest

    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?
     
    nvangogh, Feb 19, 2014
    #1
    1. Advertisements

  2. 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)
    Yes, that's pretty much what you need to do.
    std::cin.clear();

    resets the error condition on the 'std::cin' stream.
    Part of the answer can also be found in the FAQ, section 5, question 2,
    if memory serves.

    V
     
    Victor Bazarov, Feb 19, 2014
    #2
    1. Advertisements

  3. There are at least a couple of responses in comp.lang.c++.moderated.
    Please don't multipost.
     
    Barry Schwarz, Feb 19, 2014
    #3
  4. nvangogh

    James Kanze Guest

    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).
    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.
    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.
    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.)
    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.
    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).
     
    James Kanze, Feb 23, 2014
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.