【发布时间】:2013-12-20 13:40:26
【问题描述】:
这可能属于 Stack Exchange 的不同部分,但我不这么认为——programmers.se 更多的是关于其他事情。
提出问题:有些事情你可以用 std::ios::binary 做而你不能在文本模式下做(例如相对搜索),但我找不到在文本模式下你不能用二进制做的任何事情模式 - 甚至将文件作为文本读取,例如std::getline()
那么为什么我会以文本形式打开呢?作为一个可能相关的问题,为什么不默认打开二进制文件?这会破坏谁的用例?
编辑附加信息
这就是我要问的原因:
我有一个在 Windows 系统上创建的文件 - 也就是说,行结尾是 CR LF。
我用std::ifstream 使用std::ios::binary 标志打开它
我正在使用 std::getline 解析文件并获得我所期望的行为 - getline 一次读取一行。
系统:Windows 7 专业版
编译器:用于 MINGW32 的 g++
【问题讨论】:
-
不确定标准库是否这样做,但在文本文件的开头可能会有一些文本编码字节和字节顺序掩码。如果以文本模式打开,标准库可能会正确解释它们并跳过它们?但是在二进制模式下将它们视为非特殊字节?
-
曾经有这样的想法,即您将与平台无关地读写“文本文件”。因此,您想使用适合该平台的任何行分隔符。对于那些在 Windows 上使用除记事本以外的任何文本编辑器的人来说,我认为这个想法已经大行其道——在任何平台上,您都可以只编写 LF 并在阅读时接受这两种换行符。但即使你接受(不是每个人都会接受),更改默认值也是不必要的不兼容。
-
@medivh:在 Windows 上,以文本模式打开文件意味着如果文件包含
\r\n,它将被读取为\n。因此,使用默认值并期望看到\n的代码将被破坏。它将改为看到\r\n。因此,例如,您可能会在从文件读取的值上得到一个尾随\r,因为删除\n不再删除整个换行序列。 没有来自其他来源的错误\r将无法匹配等效值。 -
@medivh:所以要明确一点:因为您有一些代码在看到
\r时可以工作,您几乎可以完全确定不存在在看到 @987654332 时无法工作的有效代码@?我不认为以下 ;-) 或者您的意思是您不相信以二进制模式打开包含\r的文件会导致代码看到\r字符?这可以通过几行测试代码轻松确认。 -
@medivh 他肯定没有错。在过去的几年里,我不得不解析在 Windows 上编写的文件,在 Unix 机器上解析,而额外的
'\r'确实给我带来了额外的工作。