我尝试在互联网上研究和之间的区别cout
,但找不到完美的答案。我仍然不清楚何时使用哪个。谁能通过简单的程序向我解释并说明何时使用哪一个的完美情况?cerr
clog
我访问了这个站点cerr
,它在and上显示了一个小程序clog
,但是在那里获得的输出也可以使用cout
. 所以,我对每个人的确切用途感到困惑。
通常,您std::cout
用于正常输出、std::cerr
错误和std::clog
“记录”(可以表示任何您想要的意思)。
主要区别在于它std::cerr
不像其他两个那样缓冲。
关于旧的 Cstdout
和stderr
,std::cout
对应于stdout
,而std::cerr
和std::clog
都对应于stderr
(std::clog
缓冲除外)。
stdout
并且stderr
是不同的流,即使默认情况下它们都引用控制台输出。重定向(管道)其中一个(例如program.exe >out.txt
)不会影响另一个。
通常,stdout
应该用于实际程序输出,而所有信息和错误消息都应该打印到stderr
,这样如果用户将输出重定向到文件,信息消息仍然会打印在屏幕上而不是输出文件。
标准输出流(cout):
cout
是ostream
类的实例。cout
用于在标准输出设备上产生输出,标准输出设备通常是显示屏。需要在屏幕上显示的数据cout
使用插入运算符 ( <<
) 插入到标准输出流 ( ) 中。
无缓冲标准错误流(cerr): cerr
是用于输出错误的标准错误流。这也是ostream
该类的一个实例。由于cerr
是未缓冲的,因此当我们需要立即显示错误消息时使用它。它没有任何缓冲区来存储错误消息并稍后显示。
缓冲的标准错误流(clog):这也是ostream
类的一个实例,用于显示错误,但与cerr
错误不同的是,错误首先插入缓冲区并存储在缓冲区中,直到它没有被完全填满。
进一步阅读:基本输入输出-c
这 3 个流的区别在于缓冲。
请检查以下代码,并通过 3 行运行 DEBUG:f(std::clog)、f(std::cerr)、f(std::out),然后打开 3 个输出文件看看发生了什么。你可以交换这 3 行来看看会发生什么。
#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";
}
来自 C++17 标准文档草案:
30.4.3 窄流对象 [narrow.stream.objects]
istream cin;
1 对象
cin
控制来自与对象关联的流缓冲区的输入stdin
,在<cstdio>
(30.11.1) 中声明。2 对象
cin
初始化后,cin.tie()
返回&cout
。basic_ios<char>::init
其状态与(30.5.5.2)要求的其他状态相同。
ostream cout;
3 对象
cout
控制输出到与对象关联的流缓冲区stdout
,在<cstdio>
(30.11.1) 中声明。
ostream cerr;
4 对象
cerr
控制输出到与对象关联的流缓冲区stderr
,在<cstdio>
(30.11.1) 中声明。5 对象
cerr
初始化后,cerr.flags() & unitbuf
为非零并cerr.tie()
返回&cout
。basic_ios<char>::init
其状态与(30.5.5.2)要求的其他状态相同。
ostream clog;
6 对象
clog
控制输出到与对象关联的流缓冲区stderr
,在<cstdio>
(30.11.1) 中声明。
cout
写入stdout
;cerr
并clog
_stderr
标准输出 ( stdout
) 旨在接收来自程序的非错误、非诊断输出,例如可以显示给最终用户或流式传输到某个进一步处理阶段的成功处理的输出。
标准错误 ( stderr
) 用于诊断输出,例如指示程序没有或可能没有产生用户可能期望的输出的警告和错误消息。即使输出数据通过管道传送到进一步的处理阶段,该输入也可以显示给最终用户。
cin
并cerr
绑定到cout
它们都cout
在自己处理 I/O 操作之前刷新。cout
这确保了在程序阻止从 读取输入之前发送到的提示是可见的,并且在通过 写入错误之前刷新cin
更早的输出到ETC..cout
cerr
这与clog
- 如果你在那里写它不会被缓冲并且不绑定到任何东西,所以它会在刷新之前缓冲相当大数量的日志记录。这会产生最高的消息吞吐量,但意味着消息可能不会很快被潜在的消费者看到终端或跟踪日志。
cout和clog都是缓冲的,但cerr是非缓冲的,所有这些都是预定义的对象,它们是类 ostream 的实例。这三个的基本用途是cout用于标准输出,而clog和cerr用于显示错误。cerr未缓冲的主要原因可能是因为假设缓冲区中有多个输出并且代码中提到了错误异常,那么您需要立即显示该错误,这可以由cerr有效地完成。
如果我错了,请纠正我。