在c ++中,cout,cerr,iostream header的clog有什么区别?什么时候使用哪一个?

Arl*_*ada 81 c++ iostream cout clog

我尝试研究和互联网之间的差异cout,但无法找到一个完美的答案.我还不清楚何时使用哪个.任何人都可以通过简单的程序向我解释并说明何时使用哪一个的完美情况?cerrclog

我访问了这个网站,其显示了一个小程序cerr,并clog,但获得的输出那边也可以使用来获得cout.所以,我对每个人的确切用法感到困惑.

Som*_*ude 118

通常,您使用std::cout正常输出,std::cerr错误和std::clog"记录"(这可能意味着您想要的任何意思).

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


关于旧的C stdoutstderr,std::cout对应于stdout,while std::cerrstd::clog两者对应stderr(除了std::clog被缓冲).

  • “缓冲”是什么意思? (4认同)
  • context: cerr 不会被缓冲,因为如果程序以非正常方式崩溃,您可能会将有用的调试信息卡在缓冲区中,而不是打印到 stderr。 (3认同)
  • @simplename输出不是直接写的,而是存储在* buffer *中,直到缓冲区被*清空*。从历史上看,输出到文件或终端的速度很慢(终端或控制台的速度仍然很慢),逐个字符地写入是无效的,而写入字节块则更为有效。 (2认同)

riv*_*riv 41

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

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


Dav*_*gas 9

cerr不需要缓冲区,所以它比其他的更快并且不使用cout使用的内存,但是因为cout是缓冲的,所以在某些情况下它更有用.所以:

  • 使用cout作为标准输出.
  • 使用cerr显示错误.
  • 使用clog进行日志记录.

  • 错了,因为非缓冲,cerr比cout慢!就像写vs printf一样 (6认同)

roo*_*ler 9

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

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

缓冲标准错误流(clog):这也是ostream类的一个实例,用于显示错误但不像cerr错误首先插入缓冲区并存储在缓冲区中,直到它没有完全填充.

进一步阅读:basic-input-output-c

  • 仅供参考:看起来[TutorialsPoint.com 在这里直接抄袭了你的答案](https://www.tutorialspoint.com/What-is-the-difference- Between-cerr-and-clog-streams-in-cplusplus) 。我于 2020 年 10 月 23 日向 TutorialsPoint 发送了关于可能抄袭的电子邮件,他们于 2020 年 10 月 25 日回复说:“当然,Gabriel,我们会调查此事。”此后我再也没有收到他们的回复,但他们似乎没有调查进去。 (4认同)
  • “直到它没有完全填满。”——这不是应该说“直到它完全填满”吗? (2认同)

小智 5

这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";
}
Run Code Online (Sandbox Code Playgroud)


Ton*_*roy 5

来自 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; cerrclogstderr

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

标准错误 ( stderr) 用于诊断输出,例如表明程序没有或可能没有产生用户可能期望的输出的警告和错误消息。即使输出数据被输送到进一步的处理阶段,该输入也可以显示给最终用户。

cincerrcout

它们都cout在自己处理 I/O 操作之前刷新。这确保发送到的提示cout在程序块读取输入之前是可见的cin,并且cout在写入错误之前刷新早期的输出 to cerr,当两者都被定向到同一个终端/文件/等等..

这与clog- 如果你在那里写它不会被缓冲并且不与任何东西相关联,所以它会在刷新之前缓冲相当数量的日志记录。这产生了最高的消息吞吐量,但意味着消息可能无法快速被潜在消费者读取终端或拖尾日志看到。