Answers:
通常,您将其std::cout
用于正常输出,std::cerr
错误和std::clog
“记录”(这可能意味着您想要的意思)。
主要区别在于std::cerr
没有像其他两个缓冲那样缓冲。
关于旧的C stdout
和stderr
,std::cout
对应于stdout
,而std::cerr
和std::clog
都对应于stderr
(除了std::clog
已缓冲)。
clog
也输出到cerr
。因此,基于此,您选择哪一个?如果clog
通常用于“日志记录”,我为什么要转到错误流?日志看起来更像是“普通日志”(aka cout
)而不是错误。
cerr
并clog
使用标准的“错误”的输出,但clog
进行缓冲,这可能是为什么它似乎更喜欢cout
。选择哪个错误输出?我想取决于更多的原因,而不是我能列出的,这必须视情况而定。
标准输出流(cout):
cout
是ostream
类的实例。cout
用于在通常是显示屏的标准输出设备上产生输出。cout
使用插入运算符(<<
)将需要在屏幕上显示的数据插入到标准输出流()中。
未缓冲的标准错误流(cerr): cerr
是用于输出错误的标准错误流。这也是ostream
该类的一个实例。作为cerr
是无缓冲所以,当我们需要立即显示错误消息则使用它。它没有任何缓冲区来存储错误消息并在以后显示。
缓冲的标准错误流(clog):这也是ostream
类的实例,用于显示错误,但与错误不同cerr
的是,首先将错误插入到缓冲区中并存储在缓冲区中,直到未完全填充为止。
更多阅读:basic-input-output-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
控制输出到与(30.11.1)中stdout
声明的对象关联的流缓冲区<cstdio>
。
ostream cerr;
4对象
cerr
控制输出到与(30.11.1)中stderr
声明的对象关联的流缓冲区<cstdio>
。5对象
cerr
初始化后,cerr.flags() & unitbuf
为非零并cerr.tie()
返回&cout
。否则,其状态与basic_ios<char>::init
(30.5.5.2)所需的状态相同。
ostream clog;
6对象
clog
控制输出到与(30.11.1)中stderr
声明的对象关联的流缓冲区<cstdio>
。
cout
写道stdout
; cerr
并clog
以stderr
标准输出(stdout
)旨在从程序中接收非错误,非诊断性的输出,例如成功处理的输出,可以将其显示给最终用户或流式传输到进一步的处理阶段。
标准错误(stderr
)用于诊断输出,例如警告和错误消息,它们指示程序没有或可能没有产生用户可能期望的输出。即使将输出数据通过管道传输到进一步的处理阶段,也可以向最终用户显示此输入。
cin
并cerr
与cout
它们都cout
在自己处理I / O操作之前先刷新。这样可确保cout
在程序阻止从中读取输入之前,发送到的提示是可见的cin
,并且cout
在通过写入错误之前,将刷新到的较早输出cerr
,从而在消息都指向相同的终端/文件/时将消息按其生成的时间顺序保留等等..
与此形成对比的是clog
-如果您在此处写入内容,则不会被缓冲,也不会与任何内容绑定,因此它将在刷新之前缓冲相当数量的日志记录。这产生了最高的消息吞吐量,但是这意味着可能无法阅读该消息的潜在消费者阅读终端或尾随日志。
既COUT和阻塞被缓冲但CERR是无缓冲和所有的这些预定义其是类ostream的实例的对象。这三个的基本用法是cout用于标准输入,而clog和cerr用于显示错误。最主要的一点,为什么CERR是无缓冲IS可能是因为假设你有在缓冲区几个输出和一个错误异常的代码中提到,那么你需要立即显示错误,可以这样做CERR有效。
如果我错了,请纠正我。
cout通常用于在用户屏幕上显示一些语句。例如:cout <<“ Arlene Batada”;
输出:
阿琳·巴达达(Arlene Batada)
stdout
,stdin
(对cin
),并且stderr
它使用默认。我相信clog
这只是cerr
一个缓冲变化。