Trouble understanding exercise.

"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."

"Test your function by calling it, passing cin as an argument."

aanndd this is pretty much what I came up with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::istream& stream(std::istream& is)
{
    while (!is.eof())
    {
        cout << is;
    }

    is.clear();
    return is;
}


int main()
{
    stream(cin);

return 0;
}


What am I doing horribly wrong?
1
2
// cout << is ;
cout << is.rdbuf() ;

You can't dump an input stream to an output stream.
However, you can dump its strreambuf to an output stream.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

std::istream& stream( std::istream& is )
{
    auto pos = is.tellg() ;
    std::cout << is.rdbuf() ;
    is.clear() ;
    is.seekg(pos) ;
    return is ;
}

#include <fstream>

int main()
{
    std::ifstream stm( __FILE__ ) ;
    stream(stm) ; stream(stm) ;
}
It is almost impossible to get an eof bit set in standard input stream using stram operations (I think it is only possible if you direct a file into input stream or press Ctrl-Z (Ctrl-D on linux AFAIR) in console)
Just read a little bit on rdbuf() in the reference section here, so it's a pointer to a stream's buffer? I understand the stream buffer as a pipe that's holding data that's suppose to be passed to some kind of object/variable. Am I close?

So cout << is.rdbuf() is actually reading the data in the pipes (stream buffer) inputted from the call of stream(cin)? If that's the case:

"Use the function to print the contents of an istringstream object."

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <sstream>

using namespace std;

istream& stream(istream& is)
{
    cout << is.rdbuf();
    
    is.clear();
    return is;
}


int main()
{
    string s;
    cin >> s;

    istringstream test(s);

    stream(test);
}


Is that doing what the exercise is asking for?

@MiiNiPaa yeah I thought of letting the program run for awhile until it stops to see what happens, then pretty much figured it's stupid after 5 mins in and knew I was wrong.
> it's a pointer to a stream's buffer?

Yes. the streambuf object is the buffer and rdbuf() returns a pointer to it.


> I understand the stream buffer as a pipe that's holding data

A stream buffer holds a sequence of characters in memory; an array of characters which is a subsequence of of the characters being read or written. And the stream buffer refreshes this array as required - reading more characters in when it is empty (input) or writing the characters out when it is full (output).

See: http://www.linuxtopia.org/online_books/programming_books/c++_practical_programming/c++_practical_programming_081.html
http://www.drdobbs.com/the-standard-librarian-streambufs-and-st/184401357


> Is that doing what the exercise is asking for?

Yes.

Though these two requirements taken together are somewhat incongruous :
1. "Reset the stream so that it is valid before returning the stream."
2. "Test your function by calling it, passing cin as an argument."

There is no guaranteed, portable way to reset stdin once it reaches eof.
Thanks JLBorges for the explanation and links. I'll take this time to read and digest them. Appreciate the warning, but I guess the authors thought that would be more on the advanced side of things.
Topic archived. No new replies allowed.