C++ 什么决定从std::endl输出哪些字节
我有一个很大的代码库,它使用std::cout生成其输出,并在所有地方使用std::endl生成其换行符。这个程序似乎只为endl生成换行符,这本身并不是什么大问题,但不管出于什么原因,这并不是我所期望的 因此,作为一个现实检查,我构建了一个简单的程序,将endl注入cout,用同一个编译器编译它,并检查它的输出。该程序为endl同时发出CR和LF 看起来大程序没有用cout玩任何游戏来改变endl的工作方式,至少我不知道,所以它的行为应该与小程序不同,这似乎很奇怪。似乎大型程序必须做些什么来改变默认值。我错过了什么C++ 什么决定从std::endl输出哪些字节,c++,windows,gcc,special-characters,iostream,C++,Windows,Gcc,Special Characters,Iostream,我有一个很大的代码库,它使用std::cout生成其输出,并在所有地方使用std::endl生成其换行符。这个程序似乎只为endl生成换行符,这本身并不是什么大问题,但不管出于什么原因,这并不是我所期望的 因此,作为一个现实检查,我构建了一个简单的程序,将endl注入cout,用同一个编译器编译它,并检查它的输出。该程序为endl同时发出CR和LF 看起来大程序没有用cout玩任何游戏来改变endl的工作方式,至少我不知道,所以它的行为应该与小程序不同,这似乎很奇怪。似乎大型程序必须做些什么来改
两种程序都是使用32位Windows上的MINW GCC 4.5.2编译的。
< P> <代码> STD::EntL//C>是由C++标准定义的,执行如下:- 流a
字符李>'\n'
- 流化
I/O操纵器std::flush
“\n”
透明地转换为“\r\n”
因此,请检查您的文件是否分别以文本或二进制模式打开。C++中没有其他东西会影响这种行为。
几乎涵盖了我刚才所说的内容。当文件以“文本”模式打开时(创建文件流时的默认模式)
“\n”字符在写入文件时会转换为特定于平台的“行尾序列”。相反,从文件中读取时,“行尾序列”将转换为“\n”
注意:如果以“二进制”模式打开文件,则不会发生此转换
关于std::endl
stream << std::endl
stream补充Tomalak Geret'kal的答案:endl
扩展到特定于平台的端点这一事实是一个普遍的误解
在C/C++应用程序中,唯一的“官方”换行符(至少就流和流相关函数而言)是'\n'
。当以文本模式打开流1时(即没有ios::bin
标志),从'\n'
到平台特定换行符的转换在流1中完成
相反,endl
用于在'\n'
之后强制流刷新;这对于控制台输出可能很有用,但(1)通常情况并非如此(cout
在通过绑定流机制从cin
请求输入时会自动刷新),并且只会浪费CPU时间,(2)您经常发现它也用于文件流,而文件流几乎从来没有用过,并导致文件写入性能差
如评论中所述,就标准而言,翻译实际上可能发生在流下的任何级别(例如,流可以将有无ios::bin
转换为底层OS文件管理功能的标志,由OS负责翻译);事实上,主流操作系统没有这种翻译的特定标志,主要是因为它们的文件API与内容无关(你告诉它们要写什么,它们不做修改就写)
实际上,标准中没有关于翻译\n
“流内部”的内容。我相信这是在流和文件系统之间的接口上完成的,可能是由操作系统本身完成的。@Tomalak:没错,标准照常让实现完全自由,但我认为操作系统不应该为这种东西而烦恼,实际上,Windows上的CreateFile
或POSIX上的open
都没有“文本模式”的特殊标志,因此通常在流内部(或者如果iostream是在stdio上构建的,则在相应的C流内部)完成。好的,这是有意义的。该标准并没有明确说明将内容流式传输到文件流的含义是由实现定义的,同时也没有假装其他含义。看起来有点像一个洞,行尾转换正好穿过它@托马拉克:不过,为了安全起见,我澄清了我的答案语言标准不能合理地要求操作系统以特定的方式存储文本文件。有些操作系统很在意,有些操作系统(如IBM zOS)则将文本行存储为可变长度记录,并具有存储的记录长度,且没有分隔符。注意:我决定“在文件接口”应指“在fstream
实现中不受标准管理的部分”。。。这几乎就是全部。
stream << '\n' << std::flush;