115

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

我访问了这个站点cerr,它在and上显示了一个小程序clog,但是在那里获得的输出也可以使用cout. 所以,我对每个人的确切用途感到困惑。

4

7 回答 7

142

通常,您std::cout用于正常输出、std::cerr错误和std::clog“记录”(可以表示任何您想要的意思)。

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


关于旧的 Cstdoutstderrstd::cout对应于stdout,而std::cerrstd::clog都对应于stderrstd::clog缓冲除外)。

于 2013-05-27T12:09:18.963 回答
62

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

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

于 2013-05-27T12:17:19.777 回答
23

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

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

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

进一步阅读:基本输入输出-c

于 2017-09-12T06:45:20.653 回答
12

这 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";
}
于 2017-11-01T04:47:00.707 回答
10
  • 使用cout作为标准输出。
  • 使用cerr显示错误。
  • 使用clog进行日志记录。
于 2015-06-07T15:41:53.493 回答
5

来自 C++17 标准文档草案:

30.4.3 窄流对象 [narrow.stream.objects]

istream cin;

1 对象cin控制来自与对象关联的流缓冲区的输入stdin,在<cstdio>(30.11.1) 中声明。

2 对象cin初始化后,cin.tie()返回&coutbasic_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()返回&coutbasic_ios<char>::init其状态与(30.5.5.2)要求的其他状态相同。

ostream clog;

6 对象clog控制输出到与对象关联的流缓冲区stderr,在<cstdio>(30.11.1) 中声明。

讨论...

cout写入stdoutcerrclog_stderr

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

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

cincerr绑定到cout

它们都cout在自己处理 I/O 操作之前刷新。cout这确保了在程序阻止从 读取输入之前发送到的提示是可见的,并且在通过 写入错误之前刷新cin更早的输出到ETC..coutcerr

这与clog- 如果你在那里写它不会被缓冲并且不绑定到任何东西,所以它会在刷新之前缓冲相当大数量的日志记录。这会产生最高的消息吞吐量,但意味着消息可能不会很快被潜在的消费者看到终端或跟踪日志。

于 2018-02-26T11:28:21.583 回答
1

coutclog都是缓冲的,但cerr是非缓冲的,所有这些都是预定义的对象,它们是类 ostream 的实例。这三个的基本用途是cout用于标准输出,而clogcerr用于显示错误。cerr未缓冲的主要原因可能是因为假设缓冲区中有多个输出并且代码中提到了错误异常,那么您需要立即显示该错误,这可以由cerr有效地完成。

如果我错了,请纠正我。

于 2017-08-10T14:30:39.463 回答