How could I double output some text?cout and ofs

if I want to output something, some string or some numbers to both the screen and a file. How can I do that?

I tried:

1
2
3
string name;
ofstream ofs(name.c_str());
ofs<<cout<<"The thing I want to output";


but there will be strange memory address like string showing in file before "The thing I want to output".

If I add endl at the end of "The thing I want to output"

ofs<<cout<<"The thing I want to output"<<endl;

then looks like there won't be content in ofs.

I know two sentence will do this:

1
2
 ofs<<"The thing I want to output"<<endl;
cout<<"The thing I want to output"<<endl;


but it will become clumsy if there is a lot, is there any better way? Thanks.

Does it have to be in the program? Pipe to tee http://en.wikipedia.org/wiki/Tee_%28command%29

Plan B: Wrap the two-liner into object/function.
closed account (18hRX9L8)
You could just create a function called Write which takes two streams in the argument and writes a string to both those streams.

Example:
Write(std::cout, ofs, "The thing I want to output.\n");

EDIT:
keskiverto wrote:
Plan B: Wrap the two-liner into object/function.
Keskiverto beat me to it.
Last edited on
Thanks, keskiverto and usandfrinds!!

tee is a good option!

for the second option, if the thing I want to output is not a single type stuff(I mean: there will be strings, numbers ...), should I put them all in a stringstream first? and then do

write(cout, ofs, stringstream & ss);

???

What do you mean by wrap?

like

1
2
3
4
5
6
7
class output {
public:
    istream is;
   ifstream ifs;

???
};


How to define this kind of class and how to use it? THanks.

closed account (18hRX9L8)
Hmm... Not sure about the wrapper (I'm a noob!), but here is an example of the function we were talking about:

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

std::ofstream ofs("txt.txt", std::ofstream::out);

void Write(std::string strout) {
	std::cout << strout;
	ofs << strout;
}

int main(void) {
	std::stringstream ss;
	ss << "Tester... " << ' ' << 1 << "\n";

	Write(ss.str());

	ofs.close();

	std::cin.ignore();
	return 0;
}
usandfriends wrote:
Hmm... Not sure about the wrapper (I'm a noob!)


Maybe something like the following? (C++11 required.)

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


class MultiStream
{
    typedef std::reference_wrapper<std::ostream> element_type;
    typedef std::vector<element_type> container_type;

public:
    MultiStream(std::initializer_list<element_type>&& init_list)
        : _streams(init_list) {}

    template <typename T>
    MultiStream& print(const T& t)
    {
        for (auto& stream : _streams)
            stream.get() << t;
        return *this;
    }


private:
    container_type _streams;
};

template <typename U>
MultiStream& operator<<(MultiStream& ms, const U& u)
{
    return ms.print(u);
}

int main()
{
    std::ostringstream os;
    std::ofstream of("output.txt");

    MultiStream ms { std::cout, os, of };

    ms << "#1" << ' ' << "is #" << 1 << '\n';

    std::cout << os.str();
}
closed account (18hRX9L8)
cire wrote:
. . . code . . .

<nosarcasm>
Just tells me how much I don't know.
:)
</nosarcasm>
Last edited on
Topic archived. No new replies allowed.