在Windows上'\n'
is replaced与"\r\n"
一起出现令人不快的惊喜,我不知道。 (我猜它也在Mac上被替换了......)
是否有一种简单的方法可以确保Linux,Mac和Windows用户可以轻松地交换文本文件?
简单来说,我的意思是:不用二进制模式编写文件,或者自己测试和替换行尾字符(或者使用某些第三方程序/代码)。此问题会影响我的C ++程序执行文本文件I / O.
答案 0 :(得分:12)
问题不在于endl
,而是文本流根据系统的标准重新格式化换行符。
如果您不想这样,只需不使用文本流 - 使用二进制流。也就是说,使用ios::binary
标志打开文件。
那就是说,如果唯一的问题是用户可以交换文件,我根本不会打扰输出模式,我宁愿确保你的程序可以读取不同的格式而不用窒息。也就是说,它应该接受不同的行结尾。
这就像任何体面的文本编辑器所做的那样(但是再一次,Windows上的默认notepad.exe
是而不是一个体面的文本编辑器,并且无法正确处理Unix行符)。
答案 1 :(得分:11)
很抱歉与其他答案部分重叠,但为了完整起见:
神话: endl
“更具便携性”,因为它根据平台惯例编写了行结尾。
真相: endl
定义为向流中写'\ n',然后调用flush
。事实上,你几乎从不想使用它。
误解:您应该以文本模式打开文件以写入文本,并以二进制模式写入二进制数据。
真相:文本模式首先存在,因为前段时间有文件系统区分文本文件和二进制文件。在我所知道的任何理智平台上都不再是这样。您也可以将文本写入二进制打开的文件。事实上,这是你想要做的事情,因为它具有更好定义的语义并导致更多可移植的代码。请注意,POSIX 不区分二进制和文本模式。
如何处理文字:以二进制模式打开所有内容并使用普通的'\ n'。您还需要担心编码问题。标准化UTF-8以实现Unicode正确性。 Use UTF-8 encoded narrow-strings internally,而不是wchar_t
在不同平台上的不同。您的代码将更容易移植。
提示:默认情况下,您可以强制MSVC以二进制模式打开所有文件。它应该如下工作:
#include <stdio.h>
#include <iostream>
int main() {
_fmode = _O_BINARY;
std::ofstream f("a.txt"); // opens in binary mode
}
或者使用任何方式described here。
答案 2 :(得分:6)
如果您真的只想要一个ASCII LF,最简单的方法是以二进制模式打开文件:在非二进制模式下\ n由特定于平台的行序列末尾替换(例如,它可能被LF替换) / CR或CR / LF序列;在UNIX上它通常只是LF)。在二进制模式下,这没有完成。关闭替换也是二进制模式的唯一影响。
BTW,使用endl相当于写一个\ n,然后刷新流。通常意外的冲洗可能成为主要的性能问题。因此,endl应该很少使用,并且仅在打算使用时才使用。