我想用以下格式解析很多Lat / Long坐标 1.123456W 或 50.123456N ,基本上是一个double后跟一个char('N', 'S','W','E')。我只是想从字符串中删除字符,转换为double并在符号 W -est或 S -outh时更改符号。以下代码适用于四种情况中的三种:
适用于 1.123456W ,或 50.123456N 或 9.123456S ,但不适用于 7.123456E 。我猜测Qi解析器期望输入字符串的 E 与double的指数表示相关并因为它不完整而失败?但是,如果它失败,我如何告诉Qi跳过指数只是将字符串解码到E所在的位置?
double d;
char c;
auto const expr = boost::spirit::qi::double_ >> boost::spirit::qi::char_;
std::string tok = "7.123456E";
bool success = boost::spirit::qi::parse( tok.cbegin(), tok.cend(), expr, d, c ) ) {
if( success ) {
if( c == 'W' || c == 'w' || c == 'S' || c == 'S' ) {
d = -d;
}
/// ....
}
非常感谢!
答案 0 :(得分:2)
你走了。 Coliru编译器并不喜欢你使用auto
,因此我做了一个小修改来修复它。
查看我上面提供的RealPolicies文档。您可以基于ureal_policies
模板创建新的策略类,覆盖与指数相关的方法并从中返回false。
#include <iostream>
#include <boost/spirit/include/qi.hpp>
using namespace std;
//create a real number parser policy that doesn't handle exponent notation
template <typename T>
struct no_exp_policy : boost::spirit::qi::ureal_policies<T>
{
// No exponent
template <typename Iterator>
static bool
parse_exp(Iterator&, Iterator const&)
{
return false;
}
// No exponent
template <typename Iterator, typename Attribute>
static bool
parse_exp_n(Iterator&, Iterator const&, Attribute&)
{
return false;
}
};
int main(int argc, char **argv) {
double d;
char c;
// no_exp is a real number parser that ignores exponents and has a double attribute
boost::spirit::qi::real_parser<double, no_exp_policy<double> > no_exp;
std::string tok = "7.123456E";
bool success = boost::spirit::qi::parse( tok.cbegin(), tok.cend(),
no_exp >> boost::spirit::qi::char_("NESWnesw"),
d, c );
if( success ) {
if( c == 'W' || c == 'w' || c == 'S' || c == 's' ) {
d = -d;
}
cout << d << " " << c << endl;
}
else
cout << "failed" << endl;
return 0;
}
输出:
7.12346 E
希望这会有所帮助,但我同意它有点啰嗦。我仍然没有100%确定它不是精神错误7.12346E由默认真实解析器作为实数处理,因为恕我直言你需要在E之后有一个指数值使其有效