具体来说我很感兴趣istream& getline ( istream& is, string& str );
.是否有ifstream构造函数的选项告诉它将所有换行编码转换为引擎盖下的'\n'?我希望能够打电话getline
并优雅地处理所有行结尾.
更新:为了澄清,我希望能够编写几乎可以在任何地方编译的代码,并且几乎可以从任何地方获取输入.包括'\ r'没有'\n'的稀有文件.最大限度地减少软件用户的不便.
解决这个问题很容易,但我仍然对标准中正确处理所有文本文件格式的方式感到好奇.
getline
读取一个完整的行,直到'\n',成为一个字符串.'\n'从流中消耗,但getline不包含在字符串中.到目前为止这很好,但是在'\n'之前可能会有一个'\ r'被包含在字符串中.
有三种类型的行结尾的文本文件中看到:"\n"是Unix机器上的常规结尾,"\ r"是在旧的Mac操作系统使用,Windows使用一对(我认为),"\ r"跟随'\n'.
问题是getline
在字符串末尾留下'\ r'.
ifstream f("a_text_file_of_unknown_origin");
string line;
getline(f, line);
if(!f.fail()) { // a non-empty line was read
// BUT, there might be an '\r' at the end now.
}
Run Code Online (Sandbox Code Playgroud)
编辑感谢Neil指出这f.good()
不是我想要的.!f.fail()
是我想要的.
我可以自己手动删除它(请参阅此问题的编辑),这对于Windows文本文件很容易.但是我担心有人会输入一个只包含'\ r'的文件.在这种情况下,我认为getline将消耗整个文件,认为它是一行!
..那甚至不考虑Unicode :-)
..也许Boost有一种很好的方式从任何文本文件类型一次消耗一行?
编辑我正在使用它来处理Windows文件,但我仍然觉得我不应该这样做!这不会为'\ r'专用文件分叉.
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}
Run Code Online (Sandbox Code Playgroud)