我想读一个简单的2D int数组(空格分隔)如这里 :
qi::phrase_parse(b, e, +qi::int_ % qi::eol, qi::space - qi::eol, vectors)
有两点不同,但:
- 我希望把它变成一维的std ::向量,一行行,不分离
- 如果两行有不同数量的整数,这应被视为一个解析错误。
是否有可能做到这一点作为一个衬垫,如不写我自己的解析器? 正如简单的链接上面提到的 ?
我想读一个简单的2D int数组(空格分隔)如这里 :
qi::phrase_parse(b, e, +qi::int_ % qi::eol, qi::space - qi::eol, vectors)
有两点不同,但:
是否有可能做到这一点作为一个衬垫,如不写我自己的解析器? 正如简单的链接上面提到的 ?
假设你的意思是精神版本(“作为一个衬垫”),下面是一个改编版,增加了元件数量的检查。
如果你想要更多的控制权(和动态输入检查,而不是“事后”,),那么我建议你看一下另外一个答案我写的,显示三种方法来做到这一点:
。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/karma.hpp>
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
int main()
{
std::cin.unsetf(std::ios::skipws);
spirit::istream_iterator b(std::cin), e;
std::vector<std::vector<int> > vectors;
if (qi::phrase_parse(b, e, +qi::int_ % qi::eol >> qi::eoi, qi::blank, vectors))
{
std::cerr << "Parse failed at '" << std::string(b,e) << "'\n";
return 255;
}
// check all rows have equal amount of elements:
const auto number_of_elements = vectors.front().size();
for (auto& v : vectors)
if (v.size() != number_of_elements)
std::cerr << "Unexpected number of elements: " << v.size() << " (expected: " << number_of_elements << ")\n";
// print the data for verification
std::cout
<< karma::format(karma::right_align(8)[karma::auto_] % ',' % '\n', vectors)
<< std::endl;
return 0;
}
善缘位是没有必要的(他们只是在那里输出演示了整个事情)。
为了建立更积极的错误检查,你可以这样做:
int num_elements = 0;
bool ok = qi::phrase_parse(b, e,
(+qi::int_) [ phx::ref(num_elements) = phx::size(qi::_1) ]
>> *(qi::eol >> qi::repeat(phx::ref(num_elements)) [ qi::int_ ])
>> *qi::eol,
qi::blank, vectors);
它采用qi::repeat
期望的num_elements
在后面的行元素的个数。 你可以存储到一个一维数组:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace karma = boost::spirit::karma;
int main()
{
std::cin.unsetf(std::ios::skipws);
boost::spirit::istream_iterator b(std::cin), e;
//std::vector<std::vector<int> > vectors;
std::vector<int> vectors;
int num_elements = 0;
bool ok = qi::phrase_parse(b, e,
(+qi::int_) [ phx::ref(num_elements) = phx::size(qi::_1) ]
>> *(qi::eol >> qi::repeat(phx::ref(num_elements)) [ qi::int_ ])
>> *qi::eol,
qi::blank, vectors);
std::cout << "Detected num_elements: " << num_elements << "\n";
if (!ok)
{
std::cerr << "Parse failed at '" << std::string(b,e) << "'\n";
return 255;
}
if (b!=e)
std::cout << "Trailing unparsed: '" << std::string(b,e) << "'\n";
// print the data for verification
std::cout
<< karma::format_delimited(karma::columns(num_elements)[+karma::int_], ' ', vectors)
<< std::endl;
return 0;
}
注意使用的karma::columns(num_elements)
到输出拆分为正确的数量每行的列。