gpt4 book ai didi

c++ - 使用 boost::spirit 在 C++ 中读取二维数组

转载 作者:行者123 更新时间:2023-11-30 02:55:50 24 4
gpt4 key购买 nike

我想读取一个简单的 2D int 数组(空格分隔)为 here :

qi::phrase_parse(b, e, +qi::int_ % qi::eol, qi::space - qi::eol, vectors)

但是有两个区别:

  1. 我想将它逐行放入一维 std::vector 中,不分开
  2. 如果两行有不同数量的整数,这将被识别为解析错误。

是否可以将其作为一个类轮来执行,例如不写我自己的解析器?就像 the link mentioned above 中一样简单?

最佳答案

假设您指的是 Spirit 版本(“作为一个内衬”),下面是一个添加了元素数量检查的改编版本。

如果您想要更多的控制权(并即时检查输入,而不是“事后诸葛亮”),那么我建议您查看我写的另一个答案,其中显示了执行此操作的三种方法:

.

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

karma 位不是必需的(它们只是为了演示而输出整个内容)。

更新

要构建更主动的错误检查,您可以:

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) 将输出拆分为每行正确的列数。

关于c++ - 使用 boost::spirit 在 C++ 中读取二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16119548/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com