c++ - 如何测试 stringstream operator>> 是否解析了错误的类型并跳过它

标签 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 operator>> 是否解析了错误的类型并跳过它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24504582/

相关文章:

javascript - 删除不存在的字段的子字段

c++ - 如何强制派生类实现静态函数,该函数接收派生类的对象作为参数

c++ - 使用套接字编程的c++中的stringstream vs ifstream(ofstream)

vector 的 C++ 堆栈分配

c++ - 默认分配器是否将 int 归零?

c++ - 为什么返回前的值和返回后的值有差异?

c++ - C++ 中非常具体的解析

c++ - 如何将文件内容读入 istringstream?

C++ - 重置字符串流是否不会重置获取位置或清除标志?

c++ - 使用 ENet 从 Cereal 发送二进制数据的 StringStream