c++ - 如何测试stringstream运算符>>是否已解析错误类型并跳过它

标签 c++ stringstream

我有兴趣讨论使用stringstream解析具有多种类型的行的方法。我将从以下几行开始:

"2.832 1.3067 nana 1.678"

现在,假设我有一排长长的线,其中包含多个stringsdoubles。解决此问题的明显方法是将字符串标记化,然后检查转换每个字符串。我有兴趣跳过第二步,直接使用stringstream仅查找数字。

我想出一种解决此问题的好方法是通读字符串并检查是否已设置failbit,如果我尝试将字符串解析为 double 型,它将进行设置。

说我有以下代码:
string a("2.832 1.3067 nana 1.678");

 stringstream parser;
 parser.str(a);

 for (int i = 0; i < 4; ++i)
 {
     double b;
     parser >> b;
     if (parser.fail())
     {
         std::cout << "Failed!" << std::endl;
         parser.clear();
     }
     std::cout << b << std::endl;
 }

它将打印出以下内容:
2.832
1.3067
Failed!
0
Failed!
0

我不惊讶它无法解析字符串,但是内部发生了什么,因此无法清除failbit并解析下一个数字?

最佳答案

以下代码可以很好地跳过不良单词并收集有效的double

istringstream iss("2.832 1.3067 nana 1.678");
double num = 0;
while(iss >> num || !iss.eof()) {
    if(iss.fail()) {
        iss.clear();
        string dummy;
        iss >> dummy;
        continue;
    }
    cout << num << endl;
}

这是fully working sample

您的样本几乎正确了,只是丢失了在检测到错误格式后从流中使用无效输入字段的情况
 if (parser.fail()) {
     std::cout << "Failed!" << std::endl;
     parser.clear();
     string dummy;
     parser >> dummy;
 }

在您的情况下,提取将尝试从"nana"再次读取以进行最后一次迭代,因此将输出中的最后两行。

还要注意有关iostream::fail()的技巧,以及如何在我的第一个示例中实际测试iostream::eof()There's a well known Q&A,为什么简单地将EOF作为循环条件进行测试被认为是错误的。并且它很好地回答了当遇到意外/无效值时如何中断输入循环。但是,那里并没有说明如何跳过/忽略无效的输入字段(也没有要求输入)。

关于c++ - 如何测试stringstream运算符>>是否已解析错误类型并跳过它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64298036/

相关文章:

c++ - 引用派生类时基类的对象大小

c++ - 有关我的程序正在使用的虚拟内存的信息?

c++ - W10 + Clion,设置错误

c++ - 除非有提示,否则我的项目如何不提示 Unresolved 独立性?

c++ - 如何使用多种方式分离 token

c++ - 如何使用 Qt 网络类防止关机竞争条件

C++ stringstream to char* 转换内存分配

c++ - 如何解析文件内容并加载到 map 中

c++ - 通过函数传递字符串流值,C++