如果该流包含意外内容,在预期之前结束或未完全消耗,我如何编写一个读取std::istream
并设置正确标志的函数?
具体来说,假设我希望流包含一串字母字符后跟一个分隔符,然后是一些数字,如foo:55
。我想阅读类似
struct var {
std::string name;
double value;
};
来自溪流。我当然可以将运算符编写为
std::istream& operator>>(std::istream& s, var& x) {
std::string str;
s >> str;
size_t sep = str.find(':');
x.name = str.substr(0,sep);
x.value = atof(str.substr(sep+1).c_str());
return s;
}
但是我可以不将流内容复制到字符串吗?此外,在str
不包含整个流内容的意义上,这不适用于空格。
一周前我问了一个类似的question,但没有回复,可能是因为我在boost::program_options
的背景下将其框起来了,这些问题似乎并没有得到多少关注这里。
答案 0 :(得分:1)
您可以使用std::getline
代替s >> str
来阅读':'
,然后直接将数字读入double
,如下所示:
std::istream& operator>>(std::istream& s, var& x) {
// Skip over the leading whitespace
while (s.peek() == '\n' || s.peek() == ' ') {
s.get();
}
std::getline(s, x.name, ':');
s >> x.value;
return s;
}
答案 1 :(得分:1)
为什么不让流为您完成工作。您可以使用getline()
,>>
和istream::ignore()来阅读输入内容。
std::istream& operator>>(std::istream& s, var& x) {
// get the string part and through out the :
std::getline(s, x.name, ':');
// get the number part
s >> x.value;
// consume the newline so the next call to getline won't include it in the string part
s.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
return s;
}