C ++中的iostream标头的cout,cerr,clog有什么区别?什么时候使用哪个?


97

我尝试研究和之间的区别coutcerrclog在互联网上找不到完美的答案。我仍然不清楚何时使用哪个。谁能通过简单的程序向我解释,并说明何时使用哪种程序的理想情况?

我访问了该站点该站点cerr和上显示了一个小程序clog,但是在那获得的输出也可以使用来获得cout。因此,我对每个人的确切用法感到困惑。


6
每一个都有一个计算机识别的流,stdoutstdin(对cin),并且stderr它使用默认。我相信clog这只是cerr一个缓冲变化。
克里斯,

Answers:


48

stdout并且stderr它们是不同的流,即使它们默认情况下都引用控制台输出。重定向(管道)其中一个(例如program.exe >out.txt)不会影响另一个。

通常,stdout应将其用于实际程序输出,而所有信息和错误消息都应打印到stderr,这样,如果用户将输出重定向到文件,则信息消息仍会打印在屏幕上,而不是输出到输出文件。


131

通常,您将其std::cout用于正常输出,std::cerr错误和std::clog“记录”(这可能意味着您想要的意思)。

主要区别在于std::cerr没有像其他两个缓冲那样缓冲。


关于旧的C stdoutstderrstd::cout对应于stdout,而std::cerrstd::clog都对应于stderr(除了std::clog已缓冲)。


我读过的内容clog也输出到cerr。因此,基于此,您选择哪一个?如果clog通常用于“日志记录”,我为什么要转到错误流?日志看起来更像是“普通日志”(aka cout)而不是错误。
void.pointer

@ void.pointer正如我在答复中指出,双方cerrclog使用标准的“错误”的输出,但clog进行缓冲,这可能是为什么它似乎更喜欢cout。选择哪个错误输出?我想取决于更多的原因,而不是我能列出的,这必须视情况而定。
程序员花了

3
“缓冲”是什么意思?
simplename

5
@simplename输出不会直接写入,而是存储在缓冲区中,直到刷新缓冲区为止。从历史上看,输出到文件或终端的速度很慢(终端或控制台的速度仍然很慢),逐个字符地写入是无效的,而写入字节块则更为有效。
一些程序员哥们

14

标准输出流(cout): coutostream类的实例。cout用于在通常是显示屏的标准输出设备上产生输出。cout使用插入运算符(<<)将需要在屏幕上显示的数据插入到标准输出流()中。

未缓冲的标准错误流(cerr): cerr是用于输出错误的标准错误流。这也是ostream该类的一个实例。作为cerr无缓冲所以,当我们需要立即显示错误消息则使用它。它没有任何缓冲区来存储错误消息并在以后显示。

缓冲的标准错误流(clog):这也是ostream类的实例,用于显示错误,但与错误不同cerr的是,首先将错误插入到缓冲区中并存储在缓冲区中,直到未完全填充为止。

更多阅读:basic-input-output-c


11

这3个流的区别在于缓冲。

  1. 使用cerr,输出刷新
    • 立即(因为cerr不使用缓冲区)。
  2. 堵塞时,输出刷新
    • 完成当前功能后。
    • 显式调用函数flush。
  3. 使用cout时,输出刷新
    • 调用任何输出流(cout,cerr,clog)之后。
    • 完成当前功能后。
    • 显式调用函数flush。

请检查以下代码,并通过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";
}

10
  • 使用cout作为标准输出。
  • 使用cerr显示错误。
  • 使用木log进行记录。

6
错误的是,cerr比cout慢,因为没有缓冲!就像write vs printf
陈力

4

从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; cerrclogstderr

标准输出(stdout)旨在从程序中接收非错误,非诊断性的输出,例如成功处理的输出,可以将其显示给最终用户或流式传输到进一步的处理阶段。

标准错误(stderr)用于诊断输出,例如警告和错误消息,它们指示程序没有或可能没有产生用户可能期望的输出。即使将输出数据通过管道传输到进一步的处理阶段,也可以向最终用户显示此输入。

cincerrcout

它们都cout在自己处理I / O操作之前先刷新。这样可确保cout在程序阻止从中读取输入之前,发送到的提示是可见的cin,并且cout在通过写入错误之前,将刷新到的较早输出cerr,从而在消息都指向相同的终端/文件/时将消息按其生成的时间顺序保留等等..

与此形成对比的是clog-如果您在此处写入内容,则不会被缓冲,也不会与任何内容绑定,因此它将在刷新之前缓冲相当数量的日志记录。这产生了最高的消息吞吐量,但是这意味着可能无法阅读该消息的潜在消费者阅读终端或尾随日志。


1

COUT阻塞被缓冲但CERR是无缓冲和所有的这些预定义其是类ostream的实例的对象。这三个的基本用法是cout用于标准输入,而clogcerr用于显示错误。最主要的一点,为什么CERR是无缓冲IS可能是因为假设你有在缓冲区几个输出和一个错误异常的代码中提到,那么你需要立即显示错误,可以这样做CERR有效。

如果我错了,请纠正我。


-3

cout通常用于在用户屏幕上显示一些语句。例如:cout <<“ Arlene Batada”;

输出:

阿琳·巴达达(Arlene Batada)


这仅提及cout,并且不会尝试将其与cerr或clog进行比较。OP知道cout的作用。
JPhi1618 '18年

这不能为问题提供答案。一旦您拥有足够的声誉,您就可以在任何帖子中发表评论;相反,请提供不需要问询者澄清的答案。- 评分
kometen

@kometen确实会尝试回答问题,即使答案写得不好。相反,应该降低投票权,降低投票权更适合技术上的不准确之处。
Cristik '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.