什么决定了从std :: endl输出的字节

我有一个使用std :: cout生成输出的大型代码库,它在整个地方使用std :: endl来生成换行符。 这个程序似乎只为endl生成了换行符,这本身并不是一个大问题,但是不论什么原因,都不是我所期望的。

所以作为一个现实的检查,我build立了一个简单的程序,把endl的input到cout中,用相同的编译器编译并检查输出。 程序为endl发出CR和LF。

看起来大型程序并不像cout那样用cout来改变endl的工作方式,至less不是我能够识别的,所以看起来奇怪的是,它应该比小程序有所不同。 看起来好像这个大程序一定是在做一些改变默认设置的东西。 我在这里错过了什么?

这两个程序都是在32位窗口上使用MinGW gcc 4.5.2编译的。

为了补充Tomalak Geret'kal的回答: endl扩展到平台特定的端点是一个普遍的误解。

在C / C ++应用程序中,唯一的“官方”换行符(至少就流和与流相关的函数而言)是'\n' 。 当以文本模式打开(即没有ios::bin标志)时,从'\n'到特定于平台的换行符的转换在流 1中完成。

endl用来在'\n'之后强制刷新流; (1)通常情况并非如此(当通过绑定流机制从cin请求输入时, cout会自动刷新),并且只会浪费CPU时间,(2)您经常会发现它也使用在文件流,几乎没有用处,并导致不良的文件写入性能。


  1. 正如在评论中所讨论的,就标准而言,翻译实际上可能发生在流之下的任何级别(例如,流可以将ios::bin的存在/不存在转换成用于底层OS文件管理功能的标志,这将是操作系统的责任来做翻译); 在现实中,主流操作系统并没有特别的标志来进行这种翻译,主要是因为他们的文件API是内容不可知的(你告诉他们写什么,而不需要修改)。

std::endl由C ++标准定义来执行以下操作:

  • '\n'字符;
  • std::flush I / O操纵器。

如果您在流的另一端看到回车符,则发生在文件接口(而不是流功能本身)中; 特别是在Windows上,在文本输出到文件的过程中,您可以期望"\n"能够透明地转换为"\r\n"

因此,请检查您的文件是否分别以文本或二进制模式打开。 C ++中没有任何东西可以影响这种行为。

这个FAQ条目几乎涵盖了我刚才所说的内容。

当文件以“TEXT”模式打开时(创建文件流时默认)。

当你将它写入文件时,'\ n'字符被转换成平台特定的“行尾序列”。 相反,当从文件中读取时,“行尾序列”被转换成“\ n”。

请注意,如果以“BINARY”模式打开文件,则不会发生此转换。

关于std :: endl

 stream << std::endl 

相当于:

 stream << '\n' << std::flush; 

因此,如果你的流是一个std :: fstream(这是正常打开的),那么'\ n'字符将被转换为“行尾序列”,在某些平台上是'\ r \ n'