1

I would like to create a stream-like class through which I can write to both std::out and std::clog.

I have the following code, but the problem is that it only writes to std::clog, while the output on the console is not as expected (strangely, it overwrites itself).

struct Log : public std::ofstream
{
    Log(const std::string filename)
    : std::ofstream(filename.c_str())
    {
        std::clog.rdbuf(this->rdbuf());
    }
};

template <typename T>
Log & operator << (Log & stream, const T & x)
{
    std::cout << x;
    std::clog << x;
    return stream;
};

What I want is this

Log log("logfile.txt");
log << "this should go to the console and the logfile" << 1234 << std::endl;

Can this be done?

Stingery
  • 432
  • 4
  • 16
  • I should add that I want to leave `std::out` intact, as I want to use it "as is" in other parts of my code. – Stingery Nov 17 '14 at 11:46

2 Answers2

1

I found a (or "the") solution!

I added the following code:

Log & operator << (Log & stream, std::ostream & (*f)(std::ostream&))
{
    std::cout << f;
    std::clog << f;
    return stream;
}

This adds the functionality to also accept e.g. std::endl (or other function calls within std::ostream), which now behaves as expected.

Stingery
  • 432
  • 4
  • 16
0

There is usually no need to code up such a contraption manually to direct your output to several places.

Use tee utility for that.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 1
    You might also mention that the tee system call does largely the same thing within a C program, this would allow the user to not use a separate program. – Vality Nov 17 '14 at 11:52
  • Not sure if this is my solution. I simply want to distinguish between what I write to the console and a separate log file, which contains the same information as on the console, but many more extra lines. Hence, I do not want to write `std::cout << "info"; std::clog << "info"` (i.e. twice the same) everytime I print to the console. – Stingery Nov 17 '14 at 12:37