便携式终端(换行)

Ali*_*Ali 11 c++ portability fstream cross-platform newline

它一直是一个令人不快的意外'\n' 被替换"\r\n"在Windows上,我不知道.(我猜它也在Mac上被替换了......)

有没有一种简单的方法可以确保Linux,Mac和Windows用户可以轻松地交换文本文件?

简单来说,我的意思是:无需以二进制模式编写文件或自行测试和替换行尾字符(或使用某些第三方程序/代码).此问题会影响我的C++程序执行文本文件I/O.

Kon*_*lph 12

问题根本不endl在于,文本流根据系统的标准重新格式化换行符.

如果您不想这样,只需不使用文本流 - 使用二进制流.也就是说,用ios::binary旗帜打开你的文件.

也就是说,如果唯一的问题是用户可以交换文件,我根本不会打扰输出模式,我宁愿确保你的程序可以读取不同的格式而不会窒息.也就是说,它应该接受不同的行结尾.

这是任何体面的文本编辑器所做的事情(但同样,notepad.exeWindows上的默认值不是一个体面的文本编辑器,并且不能正确处理Unix换行符).


ybu*_*ill 11

很抱歉与其他答案部分重叠,但为了完整起见:

神话: endl "更便携",因为它根据平台惯例写出结束的行.

真相: endl被定义为向流写'\n'然后调用flush.所以事实上你几乎从不想用它.

误解:您应该以文本模式打开文件以写入文本,并以二进制模式打开文件以写入二进制数据.

真相:文本模式首先存在,因为前段时间有文件系统区分文本文件和二进制文件.在我所知道的任何理智平台上都不再是这样.您也可以将文本写入二进制打开的文件.事实上,这就是你想要做的事情,因为它具有更好定义的语义并导致更多的可移植代码.请注意,POSIX 区分二进制和文本模式.

如何做文本:以二进制模式打开所有内容并使用普通的'\n'.您还需要担心编码问题.标准化UTF-8以实现Unicode正确性.在内部使用UTF-8编码的窄字符串,而不是wchar_t在不同平台上的不同.您的代码将变得更容易移植.

提示:默认情况下,您可以强制MSVC以二进制模式打开所有文件.它应该如下工作:

#include <stdio.h>
#include <iostream>
int main() {
    _fmode = _O_BINARY;
    std::ofstream f("a.txt"); // opens in binary mode
}
Run Code Online (Sandbox Code Playgroud)

或者使用此处描述的任何方式.

  • @ybungalobill:在二进制模式下使用`'\n'`会产生Unix行结尾.在Windows上,这会破坏像记事本这样糟糕的文本编辑器以及几乎所有粘贴此类内容的文本框(即使从处理Unix行结尾的编辑器中复制)也是如此.这真的是你所倡导的,还是我完全误读了你? (2认同)

Die*_*ühl 6

如果您真的只想要一个ASCII LF,最简单的方法是以二进制模式打开文件:在非二进制模式下\n由特定于平台的行序列替换(例如,它可能被替换为LF/CR或一个CR/LF序列;在UNIX上它通常只是LF).在二进制模式下,这没有完成.关闭替换也是二进制模式的唯一影响.

顺便说一句,使用endl相当于写一个\n然后刷新流.通常意外的冲洗可能成为主要的性能问题.因此,endl应该很少使用,并且仅在意图使用flush时使用.