如何测试stringstream操作符>>已解析错误类型并跳过它 [英] How to test whether stringstream operator>> has parsed a bad type and skip it
问题描述
我对讨论使用 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"
现在假设我有一条长线,其中包含多个 strings
和 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()
.有一个众所周知的问答,为什么简单将 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操作符>>已解析错误类型并跳过它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!