I tried researching the difference between cout
, cerr
and clog
on the internet but couldn\'t find a perfect answer. I still am not cle
stdout
and stderr
are different streams, even though they both refer to console output by default. Redirecting (piping) one of them (e.g. program.exe >out.txt
) would not affect the other.
Generally, stdout
should be used for actual program output, while all information and error messages should be printed to stderr
, so that if the user redirects output to a file, information messages are still printed on the screen and not to the output file.
Standard output stream (cout):
cout
is the instance of the ostream
class. cout
is used to produce output on the standard output device which is usually the display screen. The data needed to be displayed on the screen is inserted in the standard output stream (cout
) using the insertion operator (<<
).
Un-buffered standard error stream (cerr): cerr
is the standard error stream which is used to output the errors. This is also an instance of the ostream
class. As cerr
is un-buffered so it is used when we need to display the error message immediately. It does not have any buffer to store the error message and display later.
Buffered standard error stream (clog): This is also an instance of ostream
class and used to display errors but unlike cerr
the error is first inserted into a buffer and is stored in the buffer until it is not fully filled.
further reading : basic-input-output-c
Generally you use std::cout
for normal output, std::cerr
for errors, and std::clog
for "logging" (which can mean whatever you want it to mean).
The major difference is that std::cerr
is not buffered like the other two.
In relation to the old C stdout
and stderr
, std::cout
corresponds to stdout
, while std::cerr
and std::clog
both corresponds to stderr
(except that std::clog
is buffered).
From a draft C++17 standard document:
30.4.3 Narrow stream objects [narrow.stream.objects]
istream cin;
1 The object
cin
controls input from a stream buffer associated with the objectstdin
, declared in<cstdio>
(30.11.1).2 After the object
cin
is initialized,cin.tie()
returns&cout
. Its state is otherwise the same as required forbasic_ios<char>::init
(30.5.5.2).
ostream cout;
3 The object
cout
controls output to a stream buffer associated with the objectstdout
, declared in<cstdio>
(30.11.1).
ostream cerr;
4 The object
cerr
controls output to a stream buffer associated with the objectstderr
, declared in<cstdio>
(30.11.1).5 After the object
cerr
is initialized,cerr.flags() & unitbuf
is nonzero andcerr.tie()
returns&cout
. Its state is otherwise the same as required forbasic_ios<char>::init
(30.5.5.2).
ostream clog;
6 The object
clog
controls output to a stream buffer associated with the objectstderr
, declared in<cstdio>
(30.11.1).
cout
writes to stdout
; cerr
and clog
to stderr
Standard Out (stdout
) is intended to receive non-error, non-diagnostic output from the program, such as output from successful processing that can be displayed to the end-user or streamed into some further processing stage.
Standard Error (stderr
) is intended for diagnostic output, such as warning and error messages that indicate the program hasn't or may not have produced the output the user might expect. This input may be displayed to the end user even if the output data is piped to a further processing stage.
cin
and cerr
are tied to cout
They both flush cout
before handling I/O operations themselves. This ensures prompts sent to cout
are visible before the program blocks to read input from cin
, and that earlier output to cout
is flushed before writing an error through cerr
, which keeps the messages in chronological order of their generation when both are directed to the same terminal/file/etc..
This contrasts with clog
- if you write there it won't be buffered and isn't tied to anything, so it will buffer decent sized amounts of logging before flushing. This yields the highest throughput of messages, but means the messages may not be quickly visible to a would-be consumer reading the terminal or tailing the log.
The difference of these 3 streams is buffering.
Please check the following code, and run DEBUG through 3 lines: f(std::clog), f(std::cerr), f(std::out), then open 3 output files to see what happened. You can swap these 3 lines to see what will happen.
#include <iostream>
#include <fstream>
#include <string>
void f(std::ostream &os)
{
std::cin.clear(); // clear EOF flags
std::cin.seekg(0, std::cin.beg); // seek to begin
std::string line;
while(std::getline(std::cin, line)) //input from the file in.txt
os << line << "\n"; //output to the file out.txt
}
void test()
{
std::ifstream in("in.txt");
std::ofstream out("out.txt"), err("err.txt"), log("log.txt");
std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(),
*clogbuf = std::clog.rdbuf();
std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
std::cerr.rdbuf(err.rdbuf());
std::clog.rdbuf(log.rdbuf());
f(std::clog);
f(std::cerr);
f(std::cout);
std::cin.rdbuf(cinbuf);
std::cout.rdbuf(coutbuf);
std::cerr.rdbuf(cerrbuf);
std::clog.rdbuf(clogbuf);
}
int main()
{
test();
std::cout << "123";
}