最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ JSON庫(kù)nlohmann指南

 更新時(shí)間:2025年10月27日 09:53:27   作者:alwaysrun  
本文詳細(xì)介紹了C++中流行的JSON庫(kù)nlohmann的功能與使用方法,包括聲明與構(gòu)造JSON對(duì)象、數(shù)組,解析與序列化JSON數(shù)據(jù),以及如何進(jìn)行元素的獲取、修改、刪除等常見操作,感興趣的朋友跟隨小編一起看看吧

nlohmann/json

nlohmann庫(kù)

nlohmann庫(kù)(https://github.com/nlohmann/json)提供了豐富而且符合直覺的接口(https://json.nlohmann.me/api/basic_json/),只需導(dǎo)入頭文件即可使用,方便整合到項(xiàng)目中。

聲明與構(gòu)造

可聲明普通json、數(shù)組或?qū)ο螅?/p>

using json = nlohmann::json;
json j1;
json j2 = json::object();
json j3 = json::array();

也可直接構(gòu)造(通過_json字面量,可以JSON格式直接構(gòu)造出):

json j = R"(
{
    "name": "Mike",
    "age": 15,
    "score": 85.5
}
)"_json;
json j{
    { "name", "Mike"},
    { "age", 15 },
    { "score", 85.5}
};

object生成

object可通過key-value方式賦值,或通過push_back添加:

// example for an object
json j_object = {{"one", 1},
                 {"two", 2}};
j_object["three"] = 3;
j_object.push_back({"four",4});
std::cout<<j_object<<std::endl;
for (auto &x : j_object.items()) {
    std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';
}
// {"four":4,"one":1,"three":3,"two":2}

array生成

數(shù)組可通過json::array()或聲明初始化構(gòu)造;

json j_array = {1, 2, 4};
j_array.push_back(8);
j_array.emplace_back(16);
std::cout<<j_array<<std::endl;
// key為索引,從0開始
for (auto &x : j_array.items()) {
    std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';
}
// [1,2,4,8,16]
json j_aryObj = json::array();
j_aryObj.push_back({{"one", 1}});
j_aryObj.push_back({{"two", 2}});
std::cout<<j_aryObj<<std::endl;
for (auto &x : j_aryObj) {
    std::cout << x << '\n';
}
// [{"one":1},{"two":2}]

解析與序列化

從字符串中解析:

auto j = json::parse(str);
// ...
// 序列化為字符串
std::string out = j.dump();

從文件中解析:

json j;
std::ifstream("c:\\test.json") >> j;
// ...
// 序列化到文件
std::ofstream("c:\\test.json") << j;

獲取與修改

可通過at或者operator[]的方式獲取元素的引用;然后通過get<T>()來獲取其值,直接賦值可修改其內(nèi)容:

  • at返回對(duì)象的引用,當(dāng)不存在時(shí)會(huì)拋出異常(out_of_range或parse_error):
    • at(key):根據(jù)下標(biāo)獲取數(shù)組元素;
    • at(index):根據(jù)鍵獲取對(duì)象元素;
    • at(jsonPtr):根據(jù)路徑獲取對(duì)象元素;
  • operator[]與at類似,不存在時(shí)可能會(huì)自動(dòng)添加null元素,而非拋出異常
void jsonAt() {
    json j = {
            {"number", 1},
            {"string", "foo"},
            {"array",  {1, 2}}
    };
    std::cout << j << '\n';
    std::cout << j.at("/number"_json_pointer) << '\n';
    std::cout << j.at("/string"_json_pointer) << '\n';
    std::cout << j.at("/array"_json_pointer) << '\n';
    std::cout << j.at("/array/1"_json_pointer) << '\n';
    auto ary = j.at("array");
    std::cout<<ary.at(1)<<'\n';
    auto n = j.at("number").get<int>();
    auto str = j.at("string").get<std::string>();
    std::cout<<n<<", "<<str<<'\n';
    // change the string
    j.at("/string"_json_pointer) = "bar";
    // change an array element
    j.at("/array/1"_json_pointer) = 21;
    // output the changed array
    std::cout << j["array"] << '\n';
    // out_of_range.106
    try {
        // try to use an array index with leading '0'
        json::reference ref = j.at("/array/01"_json_pointer);
    }
    catch (json::parse_error &e) {
        std::cout << e.what() << '\n';
    }
    // out_of_range.109
    try {
        // try to use an array index that is not a number
        json::reference ref = j.at("/array/one"_json_pointer);
    }
    catch (json::parse_error &e) {
        std::cout << e.what() << '\n';
    }
    // out_of_range.401
    try {
        // try to use an invalid array index
        json::reference ref = j.at("/array/4"_json_pointer);
    }
    catch (json::out_of_range &e) {
        std::cout << e.what() << '\n';
    }
    // out_of_range.403
    try {
        // try to use a JSON pointer to a nonexistent object key
        json::const_reference ref = j.at("/foo"_json_pointer);
    }
    catch (json::out_of_range &e) {
        std::cout << e.what() << '\n';
    }
}
// {"array":[1,2],"number":1,"string":"foo"}
// 1
// "foo"
// [1,2]
// 2
// 2
// 1, foo
// [1,21]
// [json.exception.parse_error.106] parse error: array index '01' must not begin with '0'
// [json.exception.parse_error.109] parse error: array index 'one' is not a number
// [json.exception.out_of_range.401] array index 4 is out of range
// [json.exception.out_of_range.403] key 'foo' not found

value

可通過value(key, defVal)來獲取元素,當(dāng)不存在時(shí)返回默認(rèn)值;但不能類型沖突(即,defValue的類型與key對(duì)應(yīng)元素的類型不匹配時(shí),會(huì)拋出type_error異常):

void jsonValue() {
    json j = {
            {"integer",  1},
            {"floating", 42.23},
            {"string",   "hello world"},
            {"boolean",  true},
            {"object",   {{"key1", 1}, {"key2", 2}}},
            {"array",    {1, 2, 3}}
        };
    // access existing values
    int v_integer = j.value("integer", 0);
    double v_floating = j.value("floating", 0.0);
    // access nonexisting values and rely on default value
    std::string v_string = j.value("nonexisting", "[none]");
    bool v_boolean = j.value("nonexisting", false);
    // output values
    std::cout << std::boolalpha << v_integer << " " << v_floating
              << " " << v_string << " " << v_boolean << "\n";
}
// 1 42.23 [none] false

是否存在contains

通過contains可判斷元素是否存在:

  • contains(key):根據(jù)鍵判斷;
  • contains(jsonPtr):根據(jù)路徑判斷(對(duì)于數(shù)組,若索引不是數(shù)字會(huì)拋出異常);

查找find

查找指定的鍵(返回iterator):iterator find(key),通過*it獲取其值;

void jsonFind() {
    // create a JSON object
    json j_object = {{"one", 1},
                     {"two", 2}};
    // call find
    auto it_two = j_object.find("two");
    auto it_three = j_object.find("three");
    // print values
    std::cout << std::boolalpha;
    std::cout << "\"two\" was found: " << (it_two != j_object.end()) << '\n';
    std::cout << "value at key \"two\": " << *it_two << '\n';
    std::cout << "\"three\" was found: " << (it_three != j_object.end()) << '\n';
}

刪除

通過erase可方便地刪除:

// {"rate":5000,"maxRate":8000,"name":"jon","more":{"count":5,"name":"mike"}}
string strJson = "{\"rate\":5000,\"maxRate\":8000,\"name\":\"jon\",\"more\":{\"count\":5,\"name\":\"mike\"}}";
auto jSet = nlohmann::json::parse(strJson);
auto ret = jSet.erase("rate");
ret = jSet.erase("name");	// ret=1
ret = jSet.erase("/more/count"); // 失敗,ret=0
auto result = jSet.dump(2);
std::cout << "result: " << result << std::endl;
// {"maxRate":8000,"more":{"count":5,"name":"mike"}}

flatten

basic_json flatten()可扁平化所有鍵(全部展開成一層key-value,key為對(duì)應(yīng)的路徑),通過unflatten可反扁平化:

void jsonFlatten() {
    // create JSON value
    json j = {{"pi",      3.14},
              {"happy",   true},
              {"name",    "Niels"},
              {"nothing", nullptr},
              {"list",    {1, 2, 3}},
              {"object",  {{"currency", "USD"}, {"value", 42.99}}}
            };
    // call flatten()
    std::cout << j.dump(2) <<'\n';
    std::cout << std::setw(4) << j.flatten() << '\n';
}
// {
//   "happy": true,
//   "list": [
//     1,
//     2,
//     3
//   ],
//   "name": "Niels",
//   "nothing": null,
//   "object": {
//     "currency": "USD",
//     "value": 42.99
//   },
//   "pi": 3.14
// }
// {
//     "/happy": true,
//     "/list/0": 1,
//     "/list/1": 2,
//     "/list/2": 3,
//     "/name": "Niels",
//     "/nothing": null,
//     "/object/currency": "USD",
//     "/object/value": 42.99,
//     "/pi": 3.14
// }

items

通過items可循環(huán)獲取所有元素:

void jsonItems(){
    // create JSON values
    json j_object = {{"one", 1}, {"two", 2}};
    json j_array = {1, 2, 4, 8, 16};
    // example for an object
    for (auto& x : j_object.items())
    {
        std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';
    }
    // example for an array
    for (auto& x : j_array.items())
    {
        std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';
    }
}

類型判斷

通過is_*判斷元素所屬類型:

  • is_array:是數(shù)組
  • is_object:是對(duì)象
  • is_null:為空
  • is_number:是數(shù)字(可繼續(xù)細(xì)化is_number_float/is_number_integer/is_number_unsigned
  • is_boolean:是布爾類型
  • is_string:是字符串
  • is_prmitive:是簡(jiǎn)單類型(非數(shù)組與對(duì)象);
  • is_strucctured:數(shù)組或?qū)ο螅?/li>

結(jié)構(gòu)體json

通過在結(jié)構(gòu)體所在的命名空間中創(chuàng)建void from_json(const json& j, MyStruct& p)可方便地從json中反序列化出結(jié)構(gòu)體;而通過void to_json(json &j, const MyStruct& p)可方便地把結(jié)構(gòu)體序列化為json;

通過get_to可把元素值賦值給類型兼容的變量:

namespace nj {
    struct Asset {
        std::string name;
        int value;
    };
    void to_json(json &j, const Asset &a) {
        j = json{{"name",  a.name},
                 {"value", a.value}};
    }
    void from_json(const json &j, Asset &a) {
        j.at("name").get_to(a.name);
        j.at("value").get_to(a.value);
    }
}

示例

json構(gòu)造與操作的示例:

void jsonBuild() {
    // {
    //  "pi": 3.141,
    //  "happy": true,
    //  "name": "Niels",
    //  "nothing": null,
    //  "answer": {
    //    	"everything": 42
    //  },
    //  "list": [1, 0, 2],
    //  "object": {
    //	    "currency": "USD",
    // 	    "value": 42.99
    //  }
    //}
    json jData;
    jData["pi"] = 3.141;
    jData["happy"] = true;
    jData["name"] = "Niels";
    jData["nothing"] = nullptr;
    jData["answer"]["everything"] = 42; // 初始化answer對(duì)象
    jData["list"] = {1, 0, 2};     // 使用列表初始化的方法對(duì)"list"數(shù)組初始化
    jData["money"] = {{"currency", "USD"},
                      {"value",    42.99}}; // 初始化object對(duì)象
    std::cout << std::boolalpha;
    std::cout << jData << std::endl;
    std::cout << jData.at("pi") << std::endl;
    std::cout << jData["pi"].get<float>() << std::endl;
    std::cout << jData["none"].is_null() << std::endl;
//    std::cout << jData.at("notAt") << std::endl; // throw exception
    std::cout << (jData.find("notFound") != jData.end()) << std::endl;
    std::cout << jData.contains("notContain") << std::endl;
    std::cout << jData.value("notExist", 0) << std::endl;
    std::cout << "sub-object" << std::endl;
    std::cout << jData.at("money") << std::endl;
    std::cout << jData.contains("currency") << std::endl;
    auto str = jData.dump(2);
    std::cout << "JSON OUT: \n";
    std::cout << str << std::endl;
//    std::cout <<jData.value("name", 0)<<std::endl; // throw exception
}
// {"answer":{"everything":42},"happy":true,"list":[1,0,2],"money":{"currency":"USD","value":42.99},"name":"Niels","nothing":null,"pi":3.141}
// 3.141
// 3.141
// true
// false
// false
// 0
// sub-object
// {"currency":"USD","value":42.99}
// false
//
// JSON OUT: 
// {
//   "answer": {
//     "everything": 42
//   },
//   "happy": true,
//   "list": [
//     1,
//     0,
//     2
//   ],
//   "money": {
//     "currency": "USD",
//     "value": 42.99
//   },
//   "name": "Niels",
//   "none": null,
//   "nothing": null,
//   "pi": 3.141
// }

以上示例可看出:

  • 通過operator[]獲取不存在的key時(shí),會(huì)添加一個(gè)值為null的鍵值對(duì);
  • 通過at獲取不存在的key時(shí),會(huì)拋出異常;
  • 通過contains與find可判斷元素是否存在;
  • 通過value獲取存在,但類型與默認(rèn)值不一致的元素時(shí),會(huì)拋出異常;

到此這篇關(guān)于C++ JSON庫(kù)nlohmann簡(jiǎn)介的文章就介紹到這了,更多相關(guān)C++ JSON庫(kù)nlohmann內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++面經(jīng)之什么是RAII面試問題解析

    C++面經(jīng)之什么是RAII面試問題解析

    這篇文章主要介紹了C++面經(jīng)之什么是RAII面試問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)圖片轉(zhuǎn)pdf

    Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)圖片轉(zhuǎn)pdf

    這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)圖片轉(zhuǎn)pdf功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以了解一下
    2022-06-06
  • C++實(shí)現(xiàn)LeetCode(205.同構(gòu)字符串)

    C++實(shí)現(xiàn)LeetCode(205.同構(gòu)字符串)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(205.同構(gòu)字符串),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • QT中start()和startTimer()的區(qū)別小結(jié)

    QT中start()和startTimer()的區(qū)別小結(jié)

    QTimer提供了定時(shí)器信號(hào)和單觸發(fā)定時(shí)器,本文主要介紹了QT中start()和startTimer()的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • C++語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 串的基本操作實(shí)例代碼

    C++語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 串的基本操作實(shí)例代碼

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 串的基本操作實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • C語(yǔ)言實(shí)現(xiàn)發(fā)送郵件功能

    C語(yǔ)言實(shí)現(xiàn)發(fā)送郵件功能

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)發(fā)送郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解C++中基類與派生類的轉(zhuǎn)換以及虛基類

    詳解C++中基類與派生類的轉(zhuǎn)換以及虛基類

    這篇文章主要介紹了詳解C++中基類與派生類的轉(zhuǎn)換以及虛基類,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C++基礎(chǔ)教程之指針拷貝詳解

    C++基礎(chǔ)教程之指針拷貝詳解

    這篇文章主要介紹了C++基礎(chǔ)教程之指針拷貝詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • C++?stack用法總結(jié)(示例詳解)

    C++?stack用法總結(jié)(示例詳解)

    std::stack?是?C++?標(biāo)準(zhǔn)模板庫(kù)(STL)中的容器適配器,它提供了棧(stack)的功能,基于其他序列容器實(shí)現(xiàn),下面給大家介紹std::stack?的用法總結(jié),感興趣的朋友一起看看吧
    2024-01-01
  • ?C++模板template原理解析

    ?C++模板template原理解析

    這篇文章主要介紹了C++模板template原理,函數(shù)模板代表了一個(gè)函數(shù)家族,該函數(shù)模板與類型無關(guān),在使用時(shí)被參數(shù)化,根據(jù)實(shí)參類型產(chǎn)生函數(shù)的特定類型版本
    2022-07-07

最新評(píng)論

东阿县| 且末县| 宝坻区| 宁城县| 八宿县| 饶平县| 绩溪县| 永川市| 曲阜市| 明光市| 江安县| 二连浩特市| 桃江县| 军事| 鱼台县| 玉溪市| 柞水县| 平果县| 思南县| 图木舒克市| 瑞丽市| 宿松县| 五原县| 关岭| 中超| 镇平县| 顺义区| 西畴县| 竹山县| 枣强县| 河曲县| 城口县| 漠河县| 清新县| 五峰| 霍州市| 鄢陵县| 嘉义县| 永寿县| 凤山市| 常熟市|