解析Lat / Long失败:没有字符'E'

时间:2014-04-16 13:24:35

标签: boost-spirit-qi

我想用以下格式解析很多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;
    }
    /// ....
}

非常感谢!

1 个答案:

答案 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之后有一个指数值使其有效