还有更多的输出缓冲区吗?如果是这样,endl
是否只刷新与cout
关联的输出缓冲区?如果只有一个缓冲区,那么是什么使这两个对象cerr
和clog
不同?
endl
刷新您流式传输到的任何流的输出缓冲区。例如:
cout << ... << endl; // flushes the output buffer of 'cout'
cerr << ... << endl; // flushes the output buffer of 'cerr'
ofstream file("filename");
file << ... << endl; // flushes the output buffer of 'file'
cerr
和 clog
之间的唯一区别是,默认情况下clog
是缓冲的,而cerr
则不是。您可以使用std::unitbuf
和std::nounitbuf
操纵器为任何流打开或关闭缓冲。例如:
cerr << nounitbuf; // cerr is now buffered
clog << unitbuf; // clog is now unbuffered
请注意,"unitbuf"的意思是"使缓冲区大小为1",即关闭缓冲。
C 语言中的 I/O(以及它起源的 UNIX 环境)是通过数据"流"完成的,数据"流"是抽象的字节序列,可以读取或写入(或两者兼而有之),例如文件系统中的文件,或终端(或屏幕和键盘)等设备。
C 标准库标头<stdio.h>
声明一个类型FILE
,该类型用作数据流的句柄。它还声明了类型 FILE*
的 stdin
、stdout
和 stderr
,以分别引用标准输入流、标准输出流和标准错误流。
C++标准库定义了可用于与数据流交互的std::istream
和std::ostream
类(统称为iostreams)(术语有点令人困惑,因为C++iostreams类有时简称为"流",但同一个词也意味着<stdio.h>
FILE'所指的抽象数据流。
全局std::istream
对象std::cin
C++与标准输入流相关联(即与stdin
引用的流相同),全局std::ostream
对象std::cout
与标准输出流相关联,全局对象std::cerr
和std::clog
是不同的对象,但都与标准错误流相关联。
cerr
和 clog
之间的区别在于,默认情况下,clog
使用 streambuf 将写入的字符存储在内部缓冲区中,并且仅在缓冲区填满或显式刷新时将该数据写入标准错误流,而 cerr
的 streambuf 不进行内部缓冲,因此所有内容都直接写入标准错误流。 因为它们是单独的对象,所以它们具有单独的 streambuf,具有不同的默认行为,但最终会写入相同的标准错误流。
std::endl
可以写入任何std::ostream
,所以如果你写std::cout << std::endl
它会刷新与cout
相关的流,这通常是标准的输出流。 如果你写std::clog << std::endl
它将刷新与clog
关联的流,这通常是标准的错误流。