我正在努力解决以跨平台的方式从文件中读取输入的问题。
不同的平台使用不同的字符序列来表示新的行/行尾。
std::getline不以跨平台的方式处理这些问题。
我这么说是什么意思?
std::getline根据编译可执行文件的平台更改其行为。在Windows平台上,它希望看到CRLF表示行尾。在Linux上,它希望只有LF.CRLF行的结尾。如果将该文件复制到Linux机器而不更改行结束格式,则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返回流对象(?)它也有一个隐式转换-bool运算符。
我可以强制return_type为bool,但这样可以防止包装函数返回流对象,如果将来需要这样的东西的话。
我也无法以足够的方式理解STL模板,以确定stream_type和string_type应该是什么。我可以强迫他们是std::ifstream和std::string,但我认为这个决定也会使函数不那么通用。
我该怎么做?
发布于 2022-05-24 13:15:50
您应该引用该流,因为通常不能复制流。此外,应该通过引用传递字符串,因为您想要写入它。
要成为通用的,您可以使用与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;
},然而,在这一点上,我被困住了。虽然getline返回流对象(?)它也有一个隐式转换-bool运算符。
转换为getline的不是bool,而是getline返回的流可以转换为bool。您的行几乎是正确的,但是它需要是一个引用(并且您不需要显式地列出类型):
auto& ret = std::getline(ifs, s);
// more code
return ret;请注意,在遇到任何分隔符之前,我并没有解决提取字符的实际问题(而不仅仅是已经在裸std::getline中获得的特定于平台的换行符)。
https://stackoverflow.com/questions/72363129
复制相似问题