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"].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中成员的数据类型

posted @ 2021-01-30 10:16  gd_沐辰  阅读(686)  评论(0编辑  收藏  举报