假设我的程序需要以下形式的参数[ 0.562 , 1.4e-2 ]
(即浮点对),我应该如何在没有正则表达式的情况下在 C++ 中解析此输入?我知道在用户输入方面需要考虑许多极端情况,但我们假设给定的输入与上述格式紧密匹配(除了进一步的空格)。
在C中,我可以做类似的事情sscanf(string, "[%g , %g]", &f1, &f2);
提取两个浮点值,非常紧凑。
在 C++ 中,这是我到目前为止所想出的:
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
字符串,但我不知道如何跳过,
两个值之间。
显而易见的方法是创建一个简单的操纵器并使用它。例如,使用静态提供的操纵器char
确定下一个非空白字符是否是该字符,如果是,则提取它可能如下所示:
#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;
}
然后,您可以使用由此构建的操纵器来提取字符:
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";
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)