読者です 読者をやめる 読者になる 読者になる

qi::repeat

C++

固定長のデータなんかを扱っていると、N回繰り返す、N文字読み飛ばす、といった処理がよく必要になります。
qi::repeatを使うと、こういった処理を簡単に記述することができます。


qi::repeatでN個読み込む、という指定は

qi::repeat(N)[ qi::char_ ]

のように書きます。
こうするとstd::vectorが返されます。

#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <pstade/oven/io.hpp>
#include <pstade/oven/identities.hpp>

int main()
{
    namespace qi = boost::spirit::qi;

    typedef std::vector<char> value_type;
    typedef qi::rule<std::string::const_iterator, value_type()> rule_type;

    const rule_type r = qi::repeat(10)[qi::char_];

    const std::string s = "1234567890ABCD";
    value_type result;
    if (!qi::parse(s.begin(), s.end(), r, result))
    {
        std::cout << "failed" << std::endl;
        return 1;
    }

    std::cout << (result | pstade::oven::identities) << std::endl;
}
{1,2,3,4,5,6,7,8,9,0}

N個の固定文字(予約領域など)を読み飛ばす場合は、

qi::repeat(N)[ qi::lit(c) ]

のように記述します(litはリテラルを意味する)。

#include <iostream>
#include <boost/spirit/include/qi.hpp>

int main()
{
    namespace qi = boost::spirit::qi;

    typedef char value_type;
    typedef qi::rule<std::string::const_iterator, value_type()> rule_type;

    const rule_type r = qi::repeat(10)[qi::lit('0')] >> qi::char_;

    const std::string s = "0000000000A";
    value_type result;
    if (!qi::parse(s.begin(), s.end(), r, result))
    {
        std::cout << "failed" << std::endl;
        return 1;
    }

    std::cout << result << std::endl;
}
A