ifstream wrapper

I'm working on a class that needs to read from cin, but also needs to read the input twice. I've decided that the mechanism I want to use is to write a simple wrapper class that will read from cin, then write to a tempporary file in the operator>> method, then it will, when the application calls seekg(0) to reset the file to the beginning of the file, my helper class will just switch the underlying stream from cin to the temporary file, then return reads from there.

I know there are some underlying issues to address if I need MORE functionality later, but for now, I know the basic functionality I need and from a logic level and how to make that happen. What I don't know how to do is handle the syntax of overloading the operator>> method.

I'm looking for a good syntax reference, or some sample code of how to properly overload this from a stream SOURCE perspective. I've written plenty of classes that overload operator>> from the DESTINATION perspective, but the exact same prototype doesn't work, at least not for primitives.

Thanks in advance!
> I know there are some underlying issues to address if I need MORE functionality later

With that caveat firmly in mind, and taking care of only formatted input, a simple (and simplistic) approach:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <sstream>
#include <string>

struct my_stream : std::istream
{
    // initially read from the stream buffer of std::cin
    my_stream() : std::istream( std::cin.rdbuf() ) {} 

    template < typename T > my_stream& operator>> ( T& v )
    {
        // for formatted input, behave exactly as a std::istream would
        if( static_cast<std::istream&>(*this) >> v ) 
               strstm << v << '\n' ; // but save what has been read into the auxiliary stream
        return *this ;
    }

    // likeweise for get(), unget(), getline() etc

    void rewind() // switch the stream buffer to the one to to which input was saved
    {
        clear() ; // just to be safe
        rdbuf( strstm.rdbuf() ) ; // switch streambuf
        strstm.clear(std::ios::failbit) ; // supress further output to strstm
    }

    std::stringstream strstm ; // contains a copy of the input
};

// overload non-member getline() (if required)

int main()
{
    my_stream stm ;
    
    int n ;
    std::string str ;
    for( int i = 0 ; i < 5 ; ++i ) // read from stdin
    {
        stm >> n >> str ;
        std::cout << "read from stdin: " << n << ' ' << str << '\n' ;
    }
    
    std::cout << "--------------------------\n" ;
    
    stm.rewind() ; // re-read what was read earlier
    while( stm >> n >> str ) std::cout << "re-read from stream: " << n << ' ' << str << '\n' ;
}

http://coliru.stacked-crooked.com/a/e88e0f5fe153f469
you're looking at the decorator pattern :).
Thanks guys! After fiddling with this code and figureing out exactly what each line does, I was able to implement a working version that'll fulfill all my needs :D
Topic archived. No new replies allowed.