【发布时间】:2011-01-25 03:25:35
【问题描述】:
谁能解释一下 cerr cout 和 clog 之间的区别以及为什么要提出不同的对象?
我知道区别如下:
1) cout 可以重定向,但 cerr 不能
2) clog 可以使用缓冲区。
我对第2点感到困惑,如果有人能详细说明,我将不胜感激。
【问题讨论】:
-
谁说 cerr 不能被重定向?我一直都这样做!
谁能解释一下 cerr cout 和 clog 之间的区别以及为什么要提出不同的对象?
我知道区别如下:
1) cout 可以重定向,但 cerr 不能
2) clog 可以使用缓冲区。
我对第2点感到困惑,如果有人能详细说明,我将不胜感激。
【问题讨论】:
输出可以是缓冲的或非缓冲的。使用缓冲输出,实现保存所有输出,直到可以方便地将其写入磁盘(或任何地方)。这很好而且很有效,但是如果程序崩溃,一些输出很可能会丢失。实现必须在发生时将无缓冲的输出写入磁盘,这可能会因大量磁盘写入而减慢速度,但除非在写入时发生程序崩溃,否则它将被写入磁盘。
标准输出和标准错误之间没有真正的功能区别;它们只是两个不同的输出流,可以分别重定向。将工具链接在一起的 Unix 理念是标准输出将具有适当的输出以进入下一个工具的输入,这几乎需要有一个单独的错误消息流。
所以,cout 写入标准输出,并被缓冲。将其用于正常输出。 cerr 写入标准错误流,并且没有缓冲。将此用于错误消息。 clog 写入标准错误流,但被缓冲。这对于执行日志记录很有用,因为它不会干扰标准输出,但效率很高(如果程序崩溃,日志的结尾可能会丢失)。
【讨论】:
缓冲输出通常比无缓冲快得多。因此,如果您想将大量数据快速写入日志(但不关心它是否真的结束了),您将使用 clog 而不是 cerr。
并且所有流通常都可以被重定向,假设一个模糊的操作系统,但这超出了 C++ 标准,它没有“重定向”这样的概念。
【讨论】:
两者都可以重定向。
在大多数实现中 cerr 不会被缓冲,不确定这是否是官方 POSIX 要求,但拥有缓冲的错误流真是太疯狂了。
使用单独的流的原因来自于 Unix 哲学,即一个程序的输出是下一个程序的输入。如果“ls”直接进行“排序”,那么在控制台上显示错误要比编写排序来了解输入是错误消息还是要排序的文本的一部分更容易。
【讨论】:
cout-Screen output(stdout)
clog-Buffered output of standard error(stderr)
cerr-Standard error device output (stderr)
【讨论】:
以程序崩溃为例,可以观察到使用缓冲和非缓冲输出的主要原因之一。
考虑一个正在将某些内容输出到日志文件中的程序。突然程序崩溃了。此时您可能有兴趣知道是什么错误导致它崩溃,但如果您对所有日志和错误使用 clog(buffered),您可能看不到所有这些信息,因为当程序崩溃时这些信息可能仍在缓冲区中,因此信息在缓冲区也丢失了。
所以在出现错误的情况下,cerr 最常用,因为它是无缓冲的,现在不会出现任何情况,因为它在缓冲区中而在程序崩溃期间丢失了一个重大错误。
【讨论】: