What决定从std::endl输出哪些字节

what determines what bytes are output from std::endl

本文关键字:字节 输出 endl std What 决定      更新时间:2023-10-16

我有一个很大的代码库,它使用std::cout来生成输出,并且到处使用std::endl来生成换行符。这个程序似乎只为endl生成换行符,这本身并不是一个大问题,但出于某种原因,这不是我所期望的。

因此,作为现实检查,我构建了一个简单的程序来将endl输入到cout中,用相同的编译器编译它并检查其输出。程序对endl同时发出CR和LF。

看起来大程序并没有玩任何游戏来改变endl的工作方式,至少我看不出来,所以它的行为与小程序不同似乎很奇怪。看起来好像大程序必须做些什么来改变默认值。我遗漏了什么?

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

再加上Tomalak Geret'kal的回答:endl扩展到特定平台的终端是一个普遍的误解。

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

相反,

endl用于强制在'n';这对于控制台输出是有用的,但是(1)通常情况并非如此(当通过绑定流机制从cin请求输入时,cout会自动刷新)并且只会浪费CPU时间,(2)您经常发现它也用于文件流,在那里它几乎没有用处,并且导致较差的文件写入性能。


  1. 正如评论中所讨论的,就标准而言,翻译实际上可能发生在流以下的任何级别(例如,流可能将ios::bin的存在/不存在转换为底层操作系统文件管理功能的标志,并且操作系统将负责进行翻译);在现实中,主流操作系统并没有针对这种翻译的特殊标志,主要是因为它们的文件api是与内容无关的(你告诉它们要写什么,它们就会不加修改地写出来)。

std::endl被c++标准定义为执行以下操作:

    输入'n'字符;
  • std::flush I/O操纵器流

如果你在流的另一端看到回车,那么这是发生在文件接口(而不是流功能本身);特别是,在Windows上,您可以期望在文本模式输出到文件期间将"n"透明地转换为"rn"

所以,检查你的文件是否分别以文本模式或二进制模式打开。c++中没有其他东西可以影响这个行为。

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

当文件以"TEXT"模式打开时(创建文件流时的默认模式)

当您将'n'字符写入文件时,它被转换为特定于平台的"行尾序列"。相反,当您从文件中读取时,"end of line sequence"将被转换为'n'。

注意,如果你以"BINARY"模式打开一个文件,这种转换不会发生。

相对于std::endl

stream << std::endl

等价于:

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

因此,如果您的流是std::fstream(正常打开),那么'n'字符将转换为"行尾序列",在某些平台上是'rn'