如何测试stringstream操作符>>已解析错误类型并跳过它 [英] How to test whether stringstream operator>> has parsed a bad type and skip it

查看:27
本文介绍了如何测试stringstream操作符>>已解析错误类型并跳过它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对讨论使用 stringstream 解析具有多种类型的行的方法很感兴趣.我将首先查看以下行:

I am interested in discussing methods for using stringstream to parse a line with multiple types. I would begin by looking at the following line:

"2.832 1.3067 nana 1.678"

现在假设我有一条长线,其中包含多个 stringsdoubles.解决这个问题的显而易见的方法是对字符串进行标记,然后检查每个字符串的转换.我有兴趣跳过这第二步并直接使用 stringstream 来只查找数字.

Now lets assume I have a long line that has multiple strings and doubles. The obvious way to solve this is to tokenize the string and then check converting each one. I am interested in skipping this second step and using stringstream directly to only find the numbers.

我想了一个解决这个问题的好方法是通读字符串并检查 failbit 是否已设置,如果我尝试将字符串解析为双精度值,就会这样做.

I figured a good way to approach this would be to read through the string and check if the failbit has been set, which it will if I try to parse a string into a 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 并解析下一个数字?

I am not surprised that it fails to parse a string, but what is happening internally such that it fails to clear its failbit and parse the next number?

推荐答案

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

The following code works well to skip the bad word and collect the valid double values

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;
}

这是一个完全可用的示例.

您的示例几乎是正确的,只是在检测到格式错误后无法使用流中的无效输入字段

Your sample almost got it right, it was just missing to consume the invalid input field from the stream after detecting it's wrong format

 if (parser.fail()) {
     std::cout << "Failed!" << std::endl;
     parser.clear();
     string dummy;
     parser >> dummy;
 }

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

In your case the extraction will try to read again from "nana" for the last iteration, hence the last two lines in the output.

还要注意关于 iostream::fail() 的技巧以及如何在我的第一个示例中实际测试 iostream::eof().有一个众所周知的问答,为什么简单将 EOF 测试为循环条件被认为是错误的.它很好地回答了如何在遇到意外/无效值时中断输入循环.但是那里没有解释如何跳过/忽略无效的输入字段(也没有被要求).

Also note the trickery about iostream::fail() and how to actually test for iostream::eof() in my 1st sample. There's a well known Q&A, why simple testing for EOF as a loop condition is considered wrong. And it answers well, how to break the input loop when unexpected/invalid values were encountered. But just how to skip/ignore invalid input fields isn't explained there (and wasn't asked for).

这篇关于如何测试stringstream操作符&gt;&gt;已解析错误类型并跳过它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆