环绕 std::getline()

Wrapping std::getline()

我正在努力解决以跨平台方式逐行读取文件输入的问题。

不同的平台使用不同的字符序列来表示新的 line/end 行。

std::getline 不会以跨平台的方式处理这些问题。

这是什么意思?

在我看来,解决此问题的最简单方法是创建一个包装 std::getline 的新函数。像这样:

return_type GetLine(stream_type ifs, string_type s)
{
    return_type ret = std::getline(ifs, s);

    s.erase(std::remove(s.begin(), s.end(), '\r' ), s.end());
    s.erase(std::remove(s.begin(), s.end(), '\n' ), s.end());

    return ret;
}

然而在这一点上我卡住了。从一些搜索中,虽然 getline returns 一个流对象(?)它也有一个隐式的转换为布尔运算符。

我可以强制 return_type 成为 bool,但这会阻止我的包装函数返回流对象,如果将来需要这样的话。

我也无法充分理解 STL 模板,无法确定 stream_typestring_type 应该是什么。我可以强制它们成为 std::ifstreamstd::string,但我认为这个决定也会使函数不那么通用。

我应该如何进行这里操作?

您应该通过引用获取流,因为流通常无法复制。此外,字符串应该通过引用传递,因为你想写入它。

要通用,您可以使用与 std::getline 相同的界面。由于您要使用特定的定界符,因此不需要将它们作为参数传递。如果您将该函数设为模板,那么它将适用于也适用于 std::getline:

的任何流
#include <iostream>
#include <sstream>
#include <string>

template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& my_getline( 
    std::basic_istream<CharT,Traits>& input,                                               
    std::basic_string<CharT,Traits,Allocator>& str) 
{                                                   
    return std::getline(input,str);
}



int main() {
    std::istringstream s{"hello world"};
    std::string foo;
    my_getline(s,foo);
    std::cout << foo;
}

However at this point I'm stuck. From some searching, although getline returns a stream object (?) it also has an implicit cast-to-bool operator.

不是getline转换为bool,而是getline返回的流可以转换为bool。你的行几乎是正确的,但它需要是一个参考(并且你不需要明确地拼出类型):

 auto& ret = std::getline(ifs, s);
 // more code
 return ret;

请注意,在遇到任何定界符之前我没有解决提取字符的实际问题(而不仅仅是您已经使用裸机 std::getline 获得的特定于平台的换行符)。