如何测试stringstream运算符>>已解析了一个坏类型并跳过它 [英] How to test whether stringstream operator>> has parsed a bad type and skip it

查看:189
本文介绍了如何测试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"

现在让我假设我有一个长线有多个字符串 doubles 。解决这个问题的明显方法是对字符串进行标记,然后检查转换每个字符串。我有兴趣跳过这个第二步,直接使用 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()有一个众所周知的Q& A ,为什么简单测试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天全站免登陆