I want to read a CSV into a struct :
struct data
{
std::string a;
std::string b;
std::string c;
}
However, I want to read even empty string to ensure all values are in their proper place. I adapted the struct to a boost::fusion, so the following works :
// Our parser (using a custom skipper to skip comments and empty lines )
template <typename Iterator, typename skipper = comment_skipper<Iterator> >
struct google_parser : qi::grammar<Iterator, addressbook(), skipper>
{
google_parser() : google_parser::base_type(contacts, "contacts")
{
using qi::eol;
using qi::eps;
using qi::_1;
using qi::_val;
using qi::repeat;
using standard_wide::char_;
using phoenix::at_c;
using phoenix::val;
value = *(char_ - ',' - eol) [_val += _1];
// This works but only for small structs
entry %= value >> ',' >> value >> ',' >> value >> eol;
}
qi::rule<Iterator, std::string()> value;
qi::rule<Iterator, data()> entry;
};
Unfortunately, repeat stores in a vector all non-empty values so the values of attributes may be mixed together (i.e if the field for b is null, it may contains the content from c):
entry %= repeat(2)[ value >> ','] >> value >> eol;
I would like to use a short rule similar to repeat as my struct has 60 attributes in practice ! Not only is writing 60 rules tedious but it seems Boost does not like long rules...
Aucun commentaire:
Enregistrer un commentaire