我尝试在互联网上研究和之间的区别cout,但找不到完美的答案。我仍然不清楚何时使用哪个。谁能通过简单的程序向我解释并说明何时使用哪一个的完美情况?cerrclog
我访问了这个站点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..coutcerr
这与clog- 如果你在那里写它不会被缓冲并且不绑定到任何东西,所以它会在刷新之前缓冲相当大数量的日志记录。这会产生最高的消息吞吐量,但意味着消息可能不会很快被潜在的消费者看到终端或跟踪日志。
cout和clog都是缓冲的,但cerr是非缓冲的,所有这些都是预定义的对象,它们是类 ostream 的实例。这三个的基本用途是cout用于标准输出,而clog和cerr用于显示错误。cerr未缓冲的主要原因可能是因为假设缓冲区中有多个输出并且代码中提到了错误异常,那么您需要立即显示该错误,这可以由cerr有效地完成。
如果我错了,请纠正我。