5

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

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

编辑——虽然问题标题涵盖了这一点,但我忘了在正文中提及:我真的想检测失败是由于格式错误,即解析,还是由于任何其他与 IO 相关的问题,以便提供适当的反馈(格式错误的异常(“x”)或其他)。

4

4 回答 4

9
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

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

于 2011-12-13T12:09:01.730 回答
4

未能提取该值将设置流的“失败”位,可以通过if (ss.fail())或仅检测到if (!ss)。等效地,您可以测试>>操作的结果,因为它返回对流的引用。

这些还将检测设置“坏”位的其他错误;你可以用ss.bad().

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

于 2011-12-13T12:12:22.413 回答
0

提取期间的错误由内部状态标志发出信号。您可以通过good()成员函数检查它们。另请参阅:http ://www.cplusplus.com/reference/iostream/stringstream

或者只是使用if()上面建议的 - 构造。这是由于流类的布尔转换运算符而起作用的

于 2011-12-13T12:13:16.283 回答
0

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

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

虽然建议istream::operator!istream::operator bool混合failbit badbit(cplusplusreference 上的 CFR此处那里)。

于 2011-12-13T22:13:37.683 回答