ostream and ofstream conversions


Hi all,

This is probably a simple issue but I can't seem to find an answer or get it to work.

My code has an ostream object that is accumulated by various modules and ultimately displayed to the console. I'd like ALSO to write this ostream object to a file, but do I have to rewrite all of that code using an ofstream object instead, or is there a way to convert one to the other (perhaps via a stringstream?)

For example, many of my existing functions look like

ostream& ClassObject::output(ostream& os) const
{
os << "Details";
return os;
}

Can I call this function with an ofstream object as the argument and have that ofstream object accumulate information instead?

Thanks for any advice!
Tom



ofstream is an ostream:
http://cplusplus.com/reference/iolibrary/

Because of this relationship, you can pass it any ostream object (or ofstream, etc.).
Thanks moorecm!
You can call a function that takes osteram& with ostringstream, ofstream, ostrstream, or any other concrete stream type. If I understood your intent correctly, you could use ostringstream, and then display it to console and to the file:

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
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

struct ClassObject {
    ostream& output(ostream&) const;
};

ostream& ClassObject::output(ostream& os) const
{
    return os << "Details";
}

int main()
{

    ClassObject c1,c2,c3;
    
    std::ostringstream buf;
    c1.output(buf);
    c2.output(buf);
    c3.output(buf);
    
    std::cout << buf.str() << '\n';
    std::ofstream fout("test.out");
    fout  << buf.str() << '\n';
}


Alternatively, you could set up a ostream that writes to cout and file simultaneously:

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
#include <iostream>
#include <fstream>
#include <sstream>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/tee.hpp>

using namespace std;

struct ClassObject {
    ostream& output(ostream&) const;
};

ostream& ClassObject::output(ostream& os) const
{
    return os << "Details";
}

namespace io = boost::iostreams;
typedef io::tee_device<std::ostream, std::ofstream> tee_t;
int main()
{

    ClassObject c1,c2,c3;
    
    std::ofstream fout("test.out");
    tee_t t(std::cout, fout);
    io::stream<tee_t> buf(t);

    c1.output(buf);
    c2.output(buf);
    c3.output(buf);
}
Wow thanks Cubbi, that really lays it all out for me, I get what's going on with these streams now. This is perfect. Thanks again!
Topic archived. No new replies allowed.