Boost Qi::p hrase_parse 只读取第一个元素

boost qi::phrase_parse reads only first element

本文关键字:读取 第一个 parse 元素 Qi hrase Boost      更新时间:2023-10-16

我已经使用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));
}

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

但这并不能解释你会读到第一个条目。

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

住在科里鲁

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));
    }
}