Difference between std::cerr and std::clog? redirecting std::clog

Hey there,

So, I've worked a little bit with the std::ostream objects and I know how to redirect std::cerr and std::cout to files but I can't find any information on how to redirect std::clog in a file. For some reason the log-stream gets redirected with the error-stream automatically.
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main(void)
{
    std::cerr << "err" << std::endl;
    std::clog << "log" << std::endl;
    std::cout << "out" << std::endl;

    return 0;
}

When i compile and do:
test.exe 2> errors.txt
this is the content of the errors.txt file:
err
log

Did I do something wrong?

I'm using Windows 8.1 if that's important
Last edited on
Both std::clog and std::cerr output to stderr. The difference is that std::cerr automatically flush all output as soon as it is written.
Ah so i can use std::clog.rdbuf(); to read the logging information?
std::clog is an output stream only; you can't read from it. However, you can redirect where it goes by replacing the stream buffer.
you can redirect where it goes by replacing the stream buffer.

How can I do that?
Use .rdbuf():
http://en.cppreference.com/w/cpp/io/basic_ios/rdbuf

You can pretty easily swap out a file stream's streambuffer with clog's streambuffer.
Okey, good to know...

I have swapped the streambuffer of clog to an other stream (an ofstream).
Peter87 mentioned that std::cerr is automatically flushed after writing something in there.
How can i modify a buffer to flush automatically?
Last edited on
You can write your own stream buffer:
http://www.mr-edd.co.uk/blog/beginners_guide_streambuf

Be aware that the operating system controls when data is written to files, so it may be impossible to immediately flush to disk.
Thank you, it works perfectly :D

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>

class log_stream : public std::ofstream
{
public:
	template <typename T>
	void operator<<(const T& data) { std::ofstream::operator<<(data); std::ofstream::flush(); }

	static log_stream& get() { static log_stream ls; return ls; }

private:
	log_stream() : std::ofstream("log_file.txt") {}
	log_stream(const log_stream&) = delete;
	void operator=(const log_stream&) = delete;
};


int main(void)
{
	std::clog.rdbuf(log_stream::get().rdbuf());

	std::cerr << "err" << std::endl;
	std::clog << "log" << std::endl;
	std::cout << "out" << std::endl;

	return 0;
}
Last edited on
In that code, defining your own streambuffer class is overkill because you don't make it do anything that ofstream's streambuffer doesn't already do.
std::clog is the standard output stream for logging, right?
I wanted to redirect that stream to a file and automatically flush it, how would you do that?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <fstream>

std::ofstream &logfile()
{
    static std::ofstream lf ("log.txt");
    return lf;
}

int main()
{
    std::clog.rdbuf(logfile().rdbuf());
    //...
}
does std::ofstream flush automatically?
All streams flush automatically. Only std::cerr writes directly to the console and skips the whole concept of flushing entirely.
Okey thank you, still thanks, I learned some things about streams today :)
Topic archived. No new replies allowed.