我特别感兴趣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.
}
编辑感谢Neil指出的f.good()
不是我想要的。!f.fail()
是我想要的
我可以自己手动删除它(请参阅此问题的编辑),这对于Windows文本文件来说很容易。但是我担心有人会提供仅包含'\ r'的文件。在这种情况下,我认为getline将消耗整个文件,以为这是一行!
..甚至都没有考虑Unicode :-)
..也许Boost有一个不错的方法来一次消耗任何文本文件类型的一行?
编辑我正在使用它来处理Windows文件,但我仍然觉得我不必这样做!而且,这不会为“ \ r”专用文件进行分叉。
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}