Istream提取操作符:如何检测解析失败

istream extraction operator: how to detect parse failure?

本文关键字:检测 失败 操作符 提取 何检测 Istream      更新时间:2023-10-16

如何检测istream提取是否失败?

string s("x");
stringstream ss(s);
int i;
ss >> std::ios::hex >> i;

EDIT——虽然问题标题涵盖了这一点,但我忘了在正文中提到:我真的想检测失败是由于格式不好,即解析,还是由于任何其他io相关问题,以便提供适当的反馈(malformmed_exception ("x")或其他)。

if(! (ss >> std::ios::hex >> i) ) 
{
  std::cerr << "stream extraction failed!" << std::endl;
}

就是这么简单。

ETA:下面是这个测试如何与流的结尾交互的一个例子。

int i;
std::stringstream sstr("1 2 3 4");
while(sstr >> i)
{
    std::cout << i << std::endl;
    if(sstr.eof())
    {
        std::cout << "eof" << std::endl;
    }
}

将打印
1
2
3
4
eof

如果在while循环条件下检查sstr.eof()sstr.good(),则不会打印4。

提取该值失败将设置流的"fail"位,该位可以由if (ss.fail())检测到,或者仅由if (!ss)检测到。同样,您可以测试>>操作的结果,因为它返回对流的引用。

这些也将检测其他错误,设置"坏"位;你可以用ss.bad()来区分它们。

如果你想继续从流中读取,你需要清除状态标志(ss.clear())。

提取过程中的错误由内部状态标志表示。您可以通过good()成员函数检查它们。详见:http://www.cplusplus.com/reference/iostream/stringstream

或者只是使用上面建议的if() -结构。这是因为流类

的bool强制转换操作符。

首先:感谢您的有用答案。然而,经过一些调查(cfr。cppreference)和验证,似乎检查解析失败的唯一方法是检查ios::failbit标志,如

const bool parsing_failed = (ss >> ios::hex >> i).rdstate() & ios::failbit ;

虽然建议的istream::operator!istream::operator bool混合了failbit badbit(参见cplusplusreference)。