boost qi::phrase_parse 只读取第一个元素
boost qi::phrase_parse reads only first element
我已经使用 boost::spirit
实现了简单的 ascii 解析器。
目标 ascii 文件看起来像
n
0 23 45 10.0 0.5
.....
n-1 x y .....
但它 returns 在 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));
}
}
我已经使用 boost::spirit
实现了简单的 ascii 解析器。
目标 ascii 文件看起来像
n
0 23 45 10.0 0.5
.....
n-1 x y .....
但它 returns 在 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));
}
}