Json常用格式

常用的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"].getstd::string();
}
} catch (const std::exception& ex) {
}
in.close();

方式二:
auto iter = j.find("deviceId");
if (iter != j.end()) {
std::string str = j["deviceId"].getstd::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::vectorstd::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::vectorstd::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::vectorstd::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::vectorstd::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::vectorstd::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::vectorstd::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::vectorstd::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::vectorstd::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").getstd::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").getstd::string();
}
//解析middleSn
if (memJson["middleSn"].is_object()) {
nlohmann::json middleJson = memJson["middleSn"];
if (middleJson.contains("smallSn") && middleJson["smallSn"].is_string()) {
smallSn = middleJson.at("smallSn").getstd::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::vectorstd::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中成员的数据类型

Json常用格式

上一篇:XCTF-WEB-backup


下一篇:蠢货之apache配置记录