Json可以理解为取代XML的一种数据格式,类似的还有YAML。
下面是来自维基百科的一个Json例子:
{
"firstName": "John",
"lastName": "Smith",
"sex": "male",
"age": 25,
"address":
{
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber":
[
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
JsonCpp是一个读取Json数据的c++工具库,本文将由简入繁最终用JsonCpp来提取维基百科这个Json例子中的各元素。
1 安装jsoncpp
在CentOS 8上安装JsonCpp的方法:
sudo dnf -y install epel-release
sudo dnf -y install jsoncpp jsoncpp-devel
在Ubuntu 2004 LTS上安装JsonCpp的方法:
sudo apt install libjsoncpp-dev
2 第一个解析Json字符串
Jsoncpp提供下面API来解析Json字符串:
class JSON_API Reader {
public:
bool parse(const std::string& document, Value& root, bool collectComments = true);
这个接口已经进入了不推荐使用的状态。我们之所以先用这个接口编程,是因为这个接口简单,容易理解。后续我们会看到最新的替代其的接口。
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
std::string str =
"{\
\"Name\":\"Tom\",\
\"Age\":20\
}";
int main()
{
Json::Reader reader;
Json::Value root;
if (reader.parse(str, root)) {
std::cout << "A: " << root["A"].asString() << std::endl;
std::cout << "B: " << root["B"].asString() << std::endl;
} else {
std::cout << "parse error" << std::endl;
}
return 0;
}
编译运行:
$ g++ a.cpp -l jsoncpp && ./a.out
Name: Tom
Age: 20
3 使用最新的接口
旧接口是这样的:
Json::Reader reader;
Json::Value root;
if (reader.parse(str, root)) {
新接口是这样,可以完全替代旧接口:
#include <memory>
Json::CharReaderBuilder builder;
const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
std::string err;
if (reader->parse(str.c_str(), str.c_str()+str.size(), &root, &err)) {
完整代码:
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>
std::string str =
"{\
\"Name\":\"Tom\",\
\"Age\":20,\
\"Children\":[\"Peter\",\"John\"]\
}";
int main()
{
// Json::Reader reader;
// Json::Value root;
// if (reader.parse(str, root)) {
Json::CharReaderBuilder builder;
const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
std::string err;
if (reader->parse(str.c_str(), str.c_str()+str.size(), &root, &err)) {
std::cout << "Name: " << root["Name"].asString() << std::endl;
std::cout << "Age: " << root["Age"].asInt() << std::endl;
int n = root["Children"].size();
std::cout << n << " Children:" << std::endl;
for (int i = 0; i < n; i++) {
std::string e = root["Children"][i].asString();
std::cout << e << " ";
}
std::cout << std::endl;
} else {
std::cout << "parse error" << std::endl;
}
return 0;
}
编译运行:
$ g++ a2.cpp -l jsoncpp && ./a.out
Name: Tom
Age: 20
2 Children:
Peter John
4 解析Json文件
Jsoncpp提供的API如下:
bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
准备Json文件:
$ cat a.json
{
"A":"a",
"B":"b"
}
源代码:
#include <iostream>
#include <fstream>
#include <jsoncpp/json/json.h>
int main()
{
std::ifstream ifs {"a.json"};
Json::Reader reader;
Json::Value root;
reader.parse(ifs, root);
std::cout << "A: " << root["A"].asString() << std::endl;
std::cout << "B: " << root["B"].asString() << std::endl;
return 0;
}
编译运行:
$ g++ c.cpp -l jsoncpp && ./a.out
A: a
B: b
5 解析维基百科中的Json例子
$ cat b.json
{
"firstName": "John",
"lastName": "Smith",
"sex": "male",
"age": 25,
"address":
{
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber":
[
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
#include <iostream>
#include <fstream>
#include <jsoncpp/json/json.h>
int main()
{
std::ifstream ifs {"b.json"};
Json::Reader reader;
Json::Value root;
reader.parse(ifs, root);
std::cout << root["lastName"].asString() << " " << root["firstName"].asString() << " ";
std::cout << root["address"]["streetAddress"].asString() << " "
<< root["address"]["city"].asString() << " "
<< root["address"]["state"].asString() << " ";
std::cout << root["phoneNumber"][0]["type"].asString() << " "
<< root["phoneNumber"][0]["number"].asString() << std::endl;
return 0;
}
$ g++ d.cpp -l jsoncpp && ./a.out
Smith John 21 2nd Street New York NY home 212 555-1234
6 参考
1 使用JsonCpp构造Json string https://www.jianshu.com/p/909a2eb4d3ebj
2 JsonCpp项目网站的example
网友评论