有关 cerr cout 和 clog 的问题

10

请问有人能解释一下cerr、cout和clog的区别,以及为什么需要不同的对象呢?

我知道它们之间的区别如下:

1)cout可以重定向,但cerr不能。

2)clog可以使用缓冲区。

关于第二点我感到困惑,如果有人能更详细地说明一下就非常感谢了。


17
谁说cerr不能被重定向?我经常这样做! - Fred Larson
5个回答

16

输出可以是缓冲的或非缓冲的。使用缓冲输出时,实现会将所有的输出保存起来直到方便时再将其写入磁盘(或其他地方)。这很高效,但如果程序崩溃,则很可能会丢失一些输出。实现必须在发生时将非缓冲输出写入磁盘,这可能会因为大量磁盘写入而变慢,但除非在写入时出现程序崩溃,否则它将被写入磁盘。

标准输出和标准错误之间没有真正的功能区别;它们只是可以单独重定向的两个不同的输出流。链式工具的Unix哲学是,标准输出将具有适当的输出以进入下一个工具的输入,这基本上要求有一个单独的流用于错误消息。

因此,cout写入标准输出,并且是缓冲的。用于正常输出。 cerr写入标准错误流中,并且是非缓冲的。用于错误消息。 clog写入标准错误流中,但是是缓冲的。这对于执行日志非常有用,因为它不会干扰标准输出,但效率很高(代价是如果程序崩溃,则日志结尾很可能会丢失)。


3

缓冲输出通常比非缓冲输出更快。因此,如果您想快速地将大量数据写入日志(但并不关心它是否实际上已经到达了那里),则应使用clog而不是cerr。

假设操作系统足够能干,所有流通常都可以重定向,但这超出了C++标准的范围,该标准没有“重定向”这样的概念。


3
你可能需要详细说明cerr/non-buffered-io的优点,即使在写操作之后出现错误,流也会被写入。 - Raphaël Saint-Pierre
@RaphaelSP 这就是我所说的“(但并不在意它是否最终到达那里)” 的意思。 - anon
1
@Neil:看起来提问者对缓冲区的概念有些困惑,我认为表达可以更清晰一些 :) - Raphaël Saint-Pierre

2

两者都可以被重定向。
在大多数实现中,cerr不会被缓冲,不确定这是否是官方POSIX要求,但将错误流缓冲起来是很疯狂的。

分离流的原因来自于Unix哲学,即一个程序的输出是下一个程序的输入。如果'ls'直接到'sort',那么在控制台上显示错误比让sort理解输入是错误消息还是您想排序的文本的一部分更容易。


1
cout-Screen output(stdout)
clog-Buffered output of standard error(stderr)
cerr-Standard error device output (stderr)

0

使用缓冲和非缓冲输出的主要原因之一可以通过以程序崩溃为例来观察。

考虑一个将某些内容输出到日志文件中的程序。突然程序崩溃了。此时,您可能会对导致程序崩溃的错误感兴趣,但如果您在所有日志和错误上都使用了clog(缓冲),则可能无法看到所有这些信息,因为当程序崩溃时,这些信息可能仍然在缓冲区中,因此缓冲区中的信息也会丢失。

因此,在出现错误的情况下,cerr通常被用作非缓冲输出,这样就不会出现由于错误信息在缓冲区中而在程序崩溃时丢失重要错误的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接