std::stringstream ss;
ss << "{ \"values\": \"A\": 1, \"B\": 10 }";
我想在下面将此流格式化为此格式。
{
"values": [
{ "A": 1, "B": 10 }
...
]
}
有人知道如何使用c ++和boost ptree解析数组的值吗?
答案 0 :(得分:6)
假设输入input.json
这是一个使用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";
}
}
相同的交易:
<强> 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);
}