【问题标题】:boost qi::phrase_parse reads only first elementboost qi::phrase_parse 只读取第一个元素
【发布时间】:2015-04-26 20:43:31
【问题描述】:

我已经使用 boost::spirit 实现了简单的 ascii 解析器。 目标 ascii 文件看起来像

n

0 23 45 10.0 0.5

.....

n-1 x y .....

但它在 measure_list 中只返回 1 个元素

如果我试图将 ASCII 读取为简单的 vector<double> 而不是结构化的,例如 - 它工作正常。怎么了?

struct measure
{
   int id;
   double x, y, size_, angle;
} 

BOOST_FUSION_ADAPT_STRUCT(measure, (int, id)(double, x)(double, y)(double, size_)(double, angel))

typedef std::vector<measure> data_t;

void RelativeMeasure(string filename)
        {
                clear();

                if(!filesystem::exists(filename)) return;

                file_name = filename;



                ifstream calibration_file(filename);

                if(calibration_file.is_open())
                {
                        int key_count;
                        calibration_file >> key_count;

                        istreambuf_iterator<char> eos;
                        istreambuf_iterator<char> it(calibration_file);

                        std::string strver(it, eos);

                        std::vector<measure> measure_list;
                        measure_list.reserve(100000);

                        qi::phrase_parse(strver.begin(), strver.end(), (qi::int_ > qi::double_ > qi::double_ > qi::double_ > qi::double_) % qi::eol, qi::blank, measure_list);

                        for each(auto measure in measure_list) key_list.push_back(KeyPoint(measure.x, measure.y, measure.size_, measure.angel));
}

【问题讨论】:

  • (double, angel)) 我想你的意思是说(double, angle))
  • 请构造一个MCVE。很难(如果不是不可能的话)从即使完整也无法编译的伪代码中分辨出真实代码中可能被破坏的内容。它可能是任何东西,从格式错误的输入数据(空行?)到代码的另一部分中的未定义行为,都会弄乱解析器。

标签: c++ boost boost-spirit-qi


【解决方案1】:

我看到的最有可能的罪魁祸首是你不吃n 之后的换行符。或许也可以使用+qi::eol 作为分隔符。

但这并不能说明你已经阅读了第一个条目。

您可以通过使用流式 API 来简化事情(在后台使用 boost::spirit::istream_iterator 多通道适配器):

Live On Coliru

void RelativeMeasure(std::string filename)
{
    std::ifstream calfile(filename, std::ios::binary);

    int key_count;
    std::vector<measure> measure_list;

    using namespace qi;
    if (
        calfile >> std::noskipws >> phrase_match(int_, blank, key_count)
        && calfile >> phrase_match(qi::repeat(key_count)[int_ > double_ > double_ > double_ > double_ > +eol], blank, measure_list)
    )
    {
        std::vector<KeyPoint> key_list;
        key_list.reserve(measure_list.size());
        // using a converting constructor (why not parse into this at once?)
        std::copy(measure_list.begin(), measure_list.end(), back_inserter(key_list));
    }
}

【讨论】:

  • 非常感谢。与 +qi::eol 的短语匹配正常工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2023-02-05
  • 1970-01-01
  • 2014-03-25
相关资源
最近更新 更多