用sscanf解析输入的C ++替代方法 [英] C++ alternative for parsing input with sscanf
问题描述
假设我的程序期望参数的形式为[ 0.562 , 1.4e-2 ]
(即成对的浮点数),那么在没有正则表达式的情况下,我该如何在C ++中解析此输入?我知道在涉及用户输入时,有很多情况需要考虑,但是让我们假设给定的输入与上述格式非常匹配(除了后面的空白).
Assuming my program expects arguments of the form [ 0.562 , 1.4e-2 ]
(i.e. pairs of floats), how should I parse this input in C++ without regular expressions? I know there are many corner cases to consider when it comes to user input, but let's assume the given input closely matches the above format (apart from further whitespace).
在C语言中,我可以执行类似sscanf(string, "[%g , %g]", &f1, &f2);
的操作来提取两个浮点值,这非常紧凑.
In C, I could do something like sscanf(string, "[%g , %g]", &f1, &f2);
to extract the two floating point values, which is very compact.
到目前为止,在C ++中,这是我想出的:
In C++, this is what I've come up with so far:
std::string s = "[ 0.562 , 1.4e-2 ]"; // example input
float f1 = 0.0f, f2 = 0.0f;
size_t leftBound = s.find('[', 0) + 1;
size_t count = s.find(']', leftBound) - leftBound;
std::istringstream ss(s.substr(leftBound, count));
string garbage;
ss >> f1 >> garbage >> f2;
if(!ss)
std::cout << "Error while parsing" << std::endl;
如何改进此代码?特别是,我担心garbage
字符串,但是我不知道如何在两个值之间跳过,
.
How could I improve this code? In particular, I'm concerned with the garbage
string, but I don't know how else to skip the ,
between the two values.
推荐答案
显而易见的方法是创建一个简单的操纵器并使用它.例如,操纵器使用静态提供的char
来确定下一个非空白字符是否为该字符,如果是,则将其提取,如下所示:
The obvious approach is to create a simple manipulator and use that. For example, a manipulator using a statically provided char
to determine if the next non-whitespace character is that character and, if so, extracts it could look like this:
#include <iostream>
#include <sstream>
template <char C>
std::istream& expect(std::istream& in)
{
if ((in >> std::ws).peek() == C) {
in.ignore();
}
else {
in.setstate(std::ios_base::failbit);
}
return in;
}
然后可以使用由此构建的操纵器提取字符:
You can then use the thus build manipulator to extract characters:
int main(int ac, char *av[])
{
std::string s(ac == 1? "[ 0.562 , 1.4e-2 ]": av[1]);
float f1 = 0.0f, f2 = 0.0f;
std::istringstream in(s);
if (in >> expect<'['> >> f1 >> expect<','> >> f2 >> expect<']'>) {
std::cout << "read f1=" << f1 << " f2=" << f2 << '\n';
}
else {
std::cout << "ERROR: failed to read '" << s << "'\n";
}
}
这篇关于用sscanf解析输入的C ++替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!