如何使用C ++解析json数组?

时间:2015-11-01 04:00:18

标签: c++ json boost

std::stringstream ss;
ss << "{ \"values\": \"A\": 1, \"B\": 10 }";

我想在下面将此流格式化为此格式。

{
  "values": [
    { "A": 1, "B": 10 }
    ...
  ]
}

有人知道如何使用c ++和boost ptree解析数组的值吗?

2 个答案:

答案 0 :(得分:6)

假设输入input.json

使用Boost Spirit V2.x

这是一个使用Boost Spirit Qi的简单方法:

<强> Live On Coliru

<div class="front-page-container-search">
    <h3>This is the text I will have in my bubble. Yet when I shrink my 
         screen the input moves down. </h3>
    <form>
      <div class="input-group myform">
        <input type="text" class="form-control" placeholder="Find artist...">
        <span class="input-group-btn">
          <button class="btn btn-default" type="submit">
            <span class="glyphicon glyphicon-search">Search</span>
          </button>
        </span>
      </div>
    </form>
  </div>

打印

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_match.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <fstream>
#include <map>

namespace {
    using Element = std::map<std::string, int>;
    struct Array : std::vector<Element> { };

    std::istream& operator>>(std::istream& is, Array& into) {
        using namespace boost::spirit::qi;
        using it = boost::spirit::istream_iterator;

        rule<it, std::string()> s;
        rule<it, Element(), space_type> r, e;

        s = '"' >> ~char_('"') >> '"';
        r = (s >> ':' >> int_) % ',';
        e = '{' >> r >> '}';

        return is >> phrase_match('{'
                    >> lit("\"values\"") >> ':' >> '[' >> (e % ',') >> ']'
                >> '}', space, into);
    }
}

int main() {
    std::ifstream ifs("input.json");
    ifs.unsetf(std::ios::skipws);

    Array array;
    if (ifs >> array) {
        std::cout << "Parsed " << array.size() << " elements:\n";

        for (auto& e : array) {
            std::cout << "\n--------------------\n{ ";
            for (auto& kv : e)
                std::cout << "\"" << kv.first << "\": " << kv.second << ", ";
            std::cout << " }\n";
        }
    } else {
        std::cout << "Parsing failed\n";
    }
}

使用Spirit X3

相同的交易:

<强> Live On Coliru

std::istream& {anonymous}::operator>>(std::istream&, {anonymous}::Array&)
Parsed 13 elements:
--------------------
{ "A": 1, "B": 10,  }
--------------------
{ "C": 3, "D": 12,  }
--------------------
{ "E": 5, "F": 14,  }
--------------------
{ "G": 7, "H": 16,  }
--------------------
{ "I": 9, "J": 18,  }
--------------------
{ "K": 11, "L": 20,  }
--------------------
{ "M": 13, "N": 22,  }
--------------------
{ "O": 15, "P": 24,  }
--------------------
{ "Q": 17, "R": 26,  }
--------------------
{ "S": 19, "T": 28,  }
--------------------
{ "U": 21, "V": 30,  }
--------------------
{ "W": 23, "X": 32,  }
--------------------
{ "Y": 25, "Z": 34,  }

具有相同namespace { using Element = std::map<std::string, int>; struct Array : std::vector<Element> { }; namespace parser { using namespace boost::spirit::x3; rule<struct rule_key_t, std::string> s; rule<struct rule_element_t, Element> r; rule<struct rule_braced_t, Element> e; auto s_def = '"' >> ~char_('"') >> '"'; auto r_def = (s >> ':' >> int_) % ','; auto e_def = '{' >> r >> '}'; BOOST_SPIRIT_DEFINE(s,r,e) } std::istream& operator>>(std::istream& is, Array& into) { using namespace parser; boost::spirit::istream_iterator f(is), l; if (!phrase_parse(f, l, '{' >> lit("\"values\"") >> ':' >> '[' >> (e % ',') >> ']' >> '}', space, into)) { is.setstate(is.rdstate() | std::ios::failbit); } return is; } }

的相同输出

使用属性树

这有点不同,我选择不实施main(),因为Boost Property并不能真正承担这一点。

<强> Live On Coliru

operator>>

当然,输出再次与之前相同。

答案 1 :(得分:0)

使用ThorsSerizlier,并使用与sehe相同的输入。

假设输入input.json

#include "ThorSerialize/JsonThor.h"
#include "ThorSerialize/SerUtil.h"
#include "ThorSerialize/Traits.h"
#include <iostream>
#include <fstream>

struct Data
{
    std::vector<std::map<std::string, int>>     values; // The values input
};
ThorsAnvil_MakeTrait(Data, values);  // Describes what can be serialized
                                     // There is a definition for all standard
                                     // types in SerUtil.h

int main()
{
    std::ifstream   dataStream("input.json");
    Data            data;

    // Automatically reads data into C++ structure.
    // Directly from a stream.
    dataStream >> ThorsAnvil::Serialize::jsonImport(data);

    // Converts a C++ structure into JSON for output to  a stream.
    std::cout << ThorsAnvil::Serialize::jsonExport(data);
}