我必须在C ++中解析字符串才能从中获取双精度数。字符串的格式类似于[(a,b) - (c,d)],其中a,b,c和d将是双变量。
我试图使用stringstrem,但它不接受const char参数,所以我现在不知道如何解决它。
我的代码现在看起来像:
ss >> "[(" >> a >> "," >> b >> ")-(" >> c >> "," >> d >> ")]";
但遗憾的是它不起作用:(
例如:[(1.2,3.4) - (6.5,7.4)]。而且我要:
a=1.2;
b=3.4;
c=6.5;
d=7.4;
使用输入流,您需要读取变量的输入。你可以用char
读入std::istream::read
或字符串。理想情况下,你会检查字符实际上是按预期,捕获并可能拒绝说__1.2-3.4@#~6.5,7.8++
char chr;
ss >> chr >> chr >> a >> chr >> b >> chr >> chr >> chr >> c >> chr >> d >> chr >> chr;
或者您可以将其作为字符串读取,然后您可以使用C ++ <regex>
功能来匹配它,可能类似于:
^\[\((\d+\.\d+),(\d+\.\d+)\)-\((\d+\.\d+),(\d+\.\d+)\)\]$
这将为您提供4个成功捕获组,然后您可以将其转换为双打。如果允许使用额外的空格,小数点是可选的等等,则可以修改此值。
如果格式有任何变化,例如有时您会得到3个数字,例如[(1.2,3.4)-(6.5,7.4)+(1.5,2)]
你需要做更多深度解析,而不是>>
操作员可以直接支持。
可能是基于ss >> chr
读取的逻辑,或者基于前一个匹配结束的位置循环正则表达式(而不是一次匹配整个字符串),尽管事情变得更加先进。
它肯定不是解决它的最优雅的方式,但它是一种人类可以阅读和维护的方式,并可能在以后轻松扩展......我更喜欢这种方式而不是正则表达式:-)
auto input = "[(1.0,2.0)-(3.0,444.555)]";
std::string in(input);
for (auto iter = in.begin(); iter < in.end(); iter++)
{
char c = *iter;
// If c == '(' or ',' parse a double number (digits or '.')
// and save it somewhere.
// else: stop parsing a number / continue
}
老实说,这是C库仍然拥有最佳工具的时代之一:
#include <cstdio>
#include <string>
#include <iostream>
int main()
{
const std::string input = "[(1.2,3.4)-(6.5,7.4)]";
double a, b, c, d;
if (std::sscanf(input.c_str(), "[(%lf,%lf)-(%lf,%lf)]", &a, &b, &c, &d) == 4)
{
std::cout << "a=" << a << '\n';
std::cout << "b=" << b << '\n';
std::cout << "c=" << c << '\n';
std::cout << "d=" << d << '\n';
}
else
{
std::cout << "Did not parse!\n";
}
}
// Output:
//
// a=1.2
// b=3.4
// c=6.5
// d=7.4
IOStreams可以做到这一点(正如Fire Lancer所展示的那样),但是在冗长的情况下,你可以自己滚动它(如Ozzy所示),但为什么要这样做呢?
还有巨大的Boost.Spirit怪物可以以“现代”的方式做到这一点,获得的收益很少。
真的,这是一个单行解决的问题。