常用的json序列化工具有jsoncpp,nlohmann.(nlohmann的使用一定要捕捉异常)
解析一些常用的json格式,上述工具的使用方式分别是什么。
备注:分割线的前者是nlohmann的使用,后者是jsoncpp的使用
序列化
nlohmann::json j="XXXXXX";
std::string str = j.dump(4); //带换行缩进,参数是缩进空格数
Json::Value value = "XXXXXX";
std::string str = value.toStyledString();
反序列化
std::string str = "XXXXXX";
nlohmann::json j = nlohmann::json::parse(str);
std::string str = "XXXXXX";
Json::Value value;
Json::Reader reader;
if (reader.parse(str, value)) {
}
磁盘存取
读取
std::ifstream in("E:\\XXXX.json");
json j;
in >> j; //json数据:j
in.close();
std::string content = j.dump(4); //string数据:content
std::ifstream in("E:\\XXXX.json");
Json::Value value;
Json::Reader reader;
if (reader.parse(in, value)) {
//json数据:value ;string数据:content
std::string content = value.toStyledString();
}
in.close();
写入
nlohmann::json j="XXXXXX";
std::ofstream out("E:\\XXXX.json");
out<<j.dump(4);
out.close();
Json::Value value="XXXXXX";
std::ofstream out("E:\\XXXX.json");
out<<value.toStyledString();
out.close();
判断字段是否存在,并且获取对应的字段
类型主要有:null,bool,object,array,string,number.
方式一:
std::ifstream in("E:\\XXXX.json");
try {
nlohmann::json j = nlohmann::json::parse(in);
if (j.contains("password") && j["password"].is_string()) {
std::string str = j["password"].get<std::string>();
}
} catch (const std::exception& ex) {
}
in.close();
方式二:
auto iter = j.find("deviceId");
if (iter != j.end()) {
std::string str = j["deviceId"].get<std::string>();
}
std::ifstream in("E:\\XXXX.json");
Json::Value value;
Json::Reader reader;
if (reader.parse(in, value)) {
if (value.isMember("password") && value["password"].isString()) {
std::string str = value["password"].asString();
}
}
in.close();
数组的序列化与反序列化
e.g.
[
"test1",
"test2",
"test3"
]
普通数组序列化到Json数组
std::vector<std::string> vet;
vet.emplace_back("test1");
vet.emplace_back("test2");
vet.emplace_back("test3");
nlohmann::json j;
for (auto &iter : vet) {
j.push_back(iter);
}
std::ofstream out("E:\\XXXX.json");
out << j.dump(4);
out.close();
std::vector<std::string> vet;
vet.emplace_back("test1");
vet.emplace_back("test2");
vet.emplace_back("test3");
Json::Value value;
for (unsigned i = 0; i < vet.size(); ++i) {
value[i] = vet[i];
}
std::ofstream out("E:\\XXXX.json");
out << value.toStyledString();
out.close();
nlohmann对于数组操作,有更为简便的优势:
std::vector<std::string> vet;
vet.emplace_back("test1");
vet.emplace_back("test2");
vet.emplace_back("test3");
nlohmann::json j(vet);
std::ofstream out("E:\\XXXX.json");
out << j.dump(4);
out.close();
反序列化Json数组到普通数组
std::vector<std::string> vet;
std::ifstream in("E:\\XXXX.json");
json j;
in >> j;
in.close();
//获取一个数组的格式
if (j.is_array()) {
for (auto iter = j.begin(); iter != j.end(); ++iter) {
std::string str = *iter;
vet.emplace_back(str);
}
}
for (auto &iter : vet) {
std::cout << iter;
}
std::vector<std::string> vet;
std::ifstream in("E:\\XXXX.json");
Json::Value value;
Json::Reader reader;
if (reader.parse(in, value)) {
if (value.isArray()) {
for (unsigned i = 0; i < value.size(); ++i) {
std::string str = value[i].asString();
vet.emplace_back(str);
}
}
}
in.close();
for (auto &iter : vet) {
std::cout << iter;
}
多层级字段的序列化与反序列化
e.g.
{
"opsSn": "Default string",
"diskSn": [
"testDisk1",
"testDisk2"
],
"memorySn": {
"bigSn": "testBig",
"middleSn": {
"smallSn": "testSmall"
}
}
}
数据序列化到Json
nlohmann::json rootJson = nlohmann::json::object();
//序列化diskSn
std::vector<std::string> vet;
vet.emplace_back("test1");
vet.emplace_back("test2");
nlohmann::json vetJson(vet);
//序列化smallSn和middleSn
nlohmann::json middleJson = nlohmann::json::object();
middleJson["smallSn"] = "testSmall";
//序列化bigSn和memorySn
nlohmann::json memJson = nlohmann::json::object();
memJson["bigSn"] = "testBig";
//各层级节点挂载
memJson["middleSn"] = middleJson;
rootJson["opsSn"] = "Default string";
rootJson["diskSn"] = vetJson;
rootJson["memorySn"] = memJson;
//序列化
std::string str = rootJson.dump(4);
std::cout << str;
Json::Value rootValue = Json::objectValue;
//序列化diskSn
std::vector<std::string> vet;
vet.emplace_back("test1");
vet.emplace_back("test2");
Json::Value vetValue = Json::arrayValue;
for (auto &iter : vet) {
vetValue.append(iter);
}
//或者
//for (unsigned i = 0; i < vet.size(); ++i) {
// //vetValue[i] = vet[i];
//}
//序列化smallSn和middleSn
Json::Value middleValue = Json::objectValue;
middleValue["smallSn"] = "testSmall";
//序列化bigSn和memorySn
Json::Value memValue = Json::objectValue;
memValue["bigSn"] = "testBig";
//各层级节点挂载
rootValue["opsSn"] = "Default string";
memValue["middleSn"] = middleValue;
rootValue["diskSn"] = vetValue;
rootValue["memorySn"] = memValue;
//序列化
std::string str = rootValue.toStyledString();
std::cout << str;
备注:nlohmann::json在STL容器兼容方面很简便。无论是vector,set,map,deque,list等
反序列化Json到数据
std::ifstream in("E:\\XXXX.json");
std::string opsSn;
std::vector<std::string> diskVet;
std::string bigSn;
std::string smallSn;
try {
nlohmann::json j = nlohmann::json::parse(in);
in.close();
//解析opsSn
if (j.contains("opsSn") && j["opsSn"].is_string()) {
opsSn = j.at("opsSn").get<std::string>();
}
//解析diskSn
if (j["diskSn"].is_array()) {
for (auto &iter : j["diskSn"]) {
std::string str = iter;
diskVet.emplace_back(str);
}
}
//解析memorySn
if (j["memorySn"].is_object()) {
nlohmann::json memJson = j["memorySn"];
if (memJson.contains("bigSn") && memJson["bigSn"].is_string()) {
bigSn = memJson.at("bigSn").get<std::string>();
}
//解析middleSn
if (memJson["middleSn"].is_object()) {
nlohmann::json middleJson = memJson["middleSn"];
if (middleJson.contains("smallSn") && middleJson["smallSn"].is_string()) {
smallSn = middleJson.at("smallSn").get<std::string>();
}
}
}
} catch (const std::exception&) {
}
std::cout << opsSn << std::endl;
for (auto &iter : diskVet) {
std::cout << iter << std::endl;
}
std::cout << bigSn << std::endl;
std::cout << smallSn << std::endl;
std::ifstream in("E:\\XXXX.json");
std::string opsSn;
std::vector<std::string> diskVet;
std::string bigSn;
std::string smallSn;
Json::Value value;
Json::Reader reader;
if (reader.parse(in, value)) {
//解析opsSn
if (value.isMember("opsSn") && value["opsSn"].isString()) {
opsSn = value["opsSn"].asString();
}
//解析diskSn
if (value["diskSn"].isArray()) {
for (unsigned i = 0; i < value["diskSn"].size(); ++i) {
std::string str = value["diskSn"][i].asString();
diskVet.emplace_back(str);
}
}
//解析memorySn
if (value["memorySn"].isObject()) {
Json::Value memValue = value["memorySn"];
if (memValue.isMember("bigSn") && memValue["bigSn"].isString()) {
bigSn = memValue["bigSn"].asString();
}
//解析middleSn
if (memValue["middleSn"].isObject()) {
Json::Value midSnValue = memValue["middleSn"];
if (midSnValue.isMember("smallSn") && midSnValue["smallSn"].isString()) {
smallSn = midSnValue["smallSn"].asString();
}
}
}
}
in.close();
std::cout << opsSn << std::endl;
for (auto &iter : diskVet) {
std::cout << iter << std::endl;
}
std::cout << bigSn << std::endl;
std::cout << smallSn << std::endl;
备注:在解析json,两者没有明显的区别与优势
Json对象里包含多个键值对(可能不知道主键,也拿到对应的值)
e.g.
{
"data":{
"test1":"this is test1",
"test2":"this is test2",
"test3":"this is test3",
"test4":"this is test4"
}
}
反序列化Json到数据
std::ifstream in("E:\\XXXX.json");
json j;
in >> j;
in.close();
std::map<std::string, std::string> dataMap;
try {
if (j["data"].is_object()) {
nlohmann::json dataJson = j["data"];
for (json::iterator it = dataJson.begin(); it != dataJson.end(); ++it) {
std::string key = it.key();
std::string val = it.value();
dataMap.insert(std::pair<std::string, std::string>(key, val));
}
}
} catch (const std::exception&) {
}
for (auto &iter : dataMap) {
std::cout << iter.first << " " << iter.second << std::endl;
}
std::ifstream in("E:\\XXXX.json");
std::map<std::string, std::string> dataMap;
Json::Reader reader;
Json::Value value;
if (reader.parse(in, value)) {
if (value["data"].isObject()) {
Json::Value dataValue = value["data"];
Json::Value::Members members = dataValue.getMemberNames();
for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it) {
std::string key = *it;
std::string val = dataValue[*it].asString();
dataMap.insert(std::pair<std::string, std::string>(key, val));
}
}
}
in.close();
for (auto &iter : dataMap) {
std::cout << iter.first << " " << iter.second << std::endl;
}
数据序列化到Json
std::map<std::string, std::string> dataMap;
dataMap.insert(std::pair<std::string, std::string>("test1", "this is test1"));
dataMap.insert(std::pair<std::string, std::string>("test2", "this is test2"));
dataMap.insert(std::pair<std::string, std::string>("test3", "this is test3"));
dataMap.insert(std::pair<std::string, std::string>("test4", "this is test4"));
//序列化data
nlohmann::json j(dataMap);
//层级挂载
nlohmann::json rootJ = nlohmann::json::object();
rootJ["data"] = j;
std::cout << rootJ.dump(4);
std::map<std::string, std::string> dataMap;
dataMap.insert(std::pair<std::string, std::string>("test1", "this is test1"));
dataMap.insert(std::pair<std::string, std::string>("test2", "this is test2"));
dataMap.insert(std::pair<std::string, std::string>("test3", "this is test3"));
dataMap.insert(std::pair<std::string, std::string>("test4", "this is test4"));
//序列化data
Json::Value dataValue = Json::objectValue;
for (auto &iter : dataMap) {
dataValue[iter.first] = iter.second;
}
//层级挂载
Json::Value rootValue = Json::objectValue;
rootValue["data"] = dataValue;
std::cout << rootValue.toStyledString();
Json与结构体的封装
namespace ns {
void to_json(json& j, const person& p) {
j = json{ { "name", p.name },{ "address", p.address },{ "age", p.age } };
}
void from_json(const json& j, person& p) {
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
} // namespace ns
优势:不需要知道person中成员的数据类型