引言
nlohman json GitHub - nlohmann/json: JSON for Modern C++ 是一個為現(xiàn)代C++(C++11)設計的JSON解析庫,主要特點是
-
易于集成,僅需一個頭文件,無需安裝依賴
-
易于使用,可以和STL無縫對接,使用體驗近似python中的json
常見用法
1. json初始化
1.1 從文件初始化
std::ifstream in_file("test.json");
nlohmann::json doc;
if (!in_file.is_open()) {
exit(1);
}
in_file >> doc;
in_file.close();
1.2 從字符串初始化
方式1
nlohmann::json doc = R"({"key1":"value1", "key2":[1,2,3]})"_json;
// nlohmann::json doc = "{\"key1\":\"value1\", \"key2\":[1,2,3]}"_json; // 此種情況下需要對json字符串中的雙引號進行轉(zhuǎn)義
-
R表示json字符串中的特殊字符均按照字符本身進行解析,而不需要進行轉(zhuǎn)義,如雙引號、反斜杠等字符
-
以 _json結(jié)尾表示其是一個json對象
方式2
std::string info = R"({"key1":"value1", "key2":[1,2,3]})";
nlohmann::json doc = nlohmann::json::parse(info);
- 調(diào)用json::parse方法,通過傳入一個字符串進行構(gòu)造,此時不以 _json結(jié)尾
1.3 直接構(gòu)造json對象
方式1
// {"key1":"value1","key2":[1,2,3],"key3":{"key":"val"}}
nlohmann::json doc = {{"key1", "value1"}, {"key2", {1,2,3}}, {"key3", {{"key", "val"}}}};
-
最外層的花括號表示一個json object
-
里面的每一對花括號的第一個元素為key,第二個元素為value,用’,'分割
-
注意:單對花括號包裹的是array,兩對花括號包裹的才是json object,如:
-
{1, 2}是一個array,即[1, 2]
-
{{1, 2}}是一個object,即{1:2},key為1,value為2
-
方式2
// {"app":"wechat","array":[1,2,4],"obj":{"age":15,"name":"zs","sex":"m"}}
nlohmann::json doc;
doc["app"] = "wechat"; // 添加一個k-v,若key存在則覆蓋value
doc["array"] = {1,2,3}; // 添加一個數(shù)組
doc["array"].emplace_back(4); // 數(shù)組添加一個元素
doc["array"].erase(2); // 刪除下標為2的元素
doc["obj"] = {{"name", "zs"}, {"age", 15}}; // 添加一個object
doc["obj"].push_back({"sex", "m"}); // 通過push方法添加一個k-v,若key存在則忽略,不會覆蓋value
doc.push_back({"app", "qq"}); // key存在,故忽略
2. json訪問
json展開如下:
{
"retCode": 0,
"retMSg": "成功",
"data": [
{
"name": "李雷",
"id": "001",
"score": {
"Chinese": 80,
"Math": 95
},
"schoolInfo": [
{
"School_name": "清華"
},
{
"School_name": "北大"
}
]
},
{
"name": "韓梅梅",
"id": "002",
"score": {
"Chinese": 90,
"Math": 80
},
"schoolInfo": [
{
"School_name": "清華"
},
{
"School_name": "北大"
}
]
}
]
}
循環(huán)遍歷
std::string info = R"({"retCode":0,"retMSg":"成功","data":[{"name":"李雷","id":"001","score":{"Chinese":80,"Math":95},"schoolInfo":[{"School_name":"清華"},{"School_name":"北大"}]},{"name":"韓梅梅","id":"002","score":{"Chinese":90,"Math":80},"schoolInfo":[{"School_name":"清華"},{"School_name":"北大"}]}]})";
try {
nlohmann::json doc = nlohmann::json::parse(info);
} catch (std::expection& e){
// json轉(zhuǎn)化失敗會拋出異常,如json格式錯誤等
std::cout << e.what() << std::endl;
}
// 循環(huán)遍歷
for (auto& item : doc.items()) {
const std::string& key = item.key();
auto& value = item.value(); // 用引用減少拷貝
if (value.is_number()) {
auto val = value.get<int>(); // 推導為int,如果是浮點型,轉(zhuǎn)化為int則只保留整數(shù)部分
// int val = value; // 強轉(zhuǎn)為int型
// auto val = value.get<uint32_t>();
// auto val = value.get<double>();
} else if (value.is_string()) {
const std::string& str = value;
// std::string str = value;
} else if (value.is_array()) { // value是一個數(shù)組
int len = value.size();
for (int i = 0; i < len; ++i) {
if (value[i].is_object()) {
;
} else if (value[i].is_string()) {
;
}
}
} else if (value.is_object()) { // value是一個json
for(auto& item_2 : value.items()) {
; // 類似處理
}
} else if (value.is_boolean()) {
bool b = value; // 或者直接用value進行傳參,他會隱式轉(zhuǎn)換為bool型
}
}
指定key遍歷
std::string info = R"({"retCode":0,"retMSg":"成功","data":[{"name":"李雷","id":"001","score":{"Chinese":80,"Math":95},"schoolInfo":[{"School_name":"清華"},{"School_name":"北大"}]},{"name":"韓梅梅","id":"002","score":{"Chinese":90,"Math":80},"schoolInfo":[{"School_name":"清華"},{"School_name":"北大"}]}]})";
nlohmann::json doc = nlohmann::json::parse(info);
if (doc.contains("retCode") && doc["retCode"].is_number()) {
int retCode = doc["retCode"];
}
if (doc.contains("data") && doc["data"].is_array()) {
nlohmann::json& doc_arr = doc["data"];
int len = doc_arr.size();
} else if (doc.contains("data") && doc["data"].is_object()) {
nlohmann::json& doc_json = doc["data"];
}
訪問key的幾種方式
// 1. 直接通過key訪問
std::string retMsg = doc["retMSg"]; // key不存在會出core(所以要判斷key是否存在),類型轉(zhuǎn)換失敗也會core
// 2. 通過at方法訪問
std::string retMsg = doc.at("retMSg"); // 同上,不同點在于at方法可以拋出異常(如果key不存在)
-
兩種方式正常情況下返回的結(jié)果都是nlohmann::json對象,并且可以隱式轉(zhuǎn)化為string以及各種基本類型
-
為了避免上述可能出現(xiàn)的問題,直接訪問key對應的value時,盡量按如下方式編寫程序:
-
先判斷key是否存在(contains)
-
再判斷key的類型,key類型相關的判斷方法如下:
方法 含義 is_number 是否為數(shù)字(int、uint32_t、uint64_t、double等) is_boolean 是否為bool is_string 是否為字符串 is_array 是否為數(shù)組 is_object 是否為json -
-
當然也可以通過捕獲異常的方式來達到避免程序出錯的目的,注意由于doc[“retMSg”]這種訪問方式不能拋出異常,應該使用doc.at(“retMSg”)這種方式來訪問。
3. json序列化
json序列化就是將json對象序列化成json格式的字符串或者存儲到文本文件
序列化為json字符串文章來源:http://www.zghlxwxcb.cn/news/detail-682785.html
string str = doc.dump();
保存為json文件文章來源地址http://www.zghlxwxcb.cn/news/detail-682785.html
nlohmann::json doc;
doc["app"] = "wechat";
doc["age"] = 17;
std::ofstream out_file("test.json");
out_file << doc;
到了這里,關于【C++】使用 nlohmann 解析 json 文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!