【C++】使用 nlohmann 解析 json 文件

这篇具有很好参考价值的文章主要介绍了【C++】使用 nlohmann 解析 json 文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

nlohman json GitHub - nlohmann/json: JSON for Modern C++ 是一个为现代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字符串中的双引号进行转义
  • R表示json字符串中的特殊字符均按照字符本身进行解析,而不需要进行转义,如双引号、反斜杠等字符

  • _json结尾表示其是一个json对象

方式2

std::string info = R"({"key1":"value1", "key2":[1,2,3]})";
nlohmann::json doc = nlohmann::json::parse(info);
  • 调用json::parse方法,通过传入一个字符串进行构造,此时不以 _json结尾
1.3 直接构造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}; // 添加一个数组
doc["array"].emplace_back(4); // 数组添加一个元素
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": "北大"
        }
      ]
    }
  ]
}

循环遍历

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转化失败会抛出异常,如json格式错误等
    std::cout << e.what() << std::endl;
}
// 循环遍历
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,如果是浮点型,转化为int则只保留整数部分
        // int val = value;          // 强转为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是一个数组
        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进行传参,他会隐式转换为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是否存在),类型转换失败也会core
// 2. 通过at方法访问
std::string retMsg = doc.at("retMSg"); // 同上,不同点在于at方法可以抛出异常(如果key不存在)
  • 两种方式正常情况下返回的结果都是nlohmann::json对象,并且可以隐式转化为string以及各种基本类型

  • 为了避免上述可能出现的问题,直接访问key对应的value时,尽量按如下方式编写程序:

    1. 先判断key是否存在(contains)

    2. 再判断key的类型,key类型相关的判断方法如下:

    方法 含义
    is_number 是否为数字(int、uint32_t、uint64_t、double等)
    is_boolean 是否为bool
    is_string 是否为字符串
    is_array 是否为数组
    is_object 是否为json
  • 当然也可以通过捕获异常的方式来达到避免程序出错的目的,注意由于doc[“retMSg”]这种访问方式不能抛出异常,应该使用doc.at(“retMSg”)这种方式来访问。

3. json序列化

json序列化就是将json对象序列化成json格式的字符串或者存储到文本文件

序列化为json字符串

string str = doc.dump();

保存为json文件文章来源地址https://www.toymoban.com/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 文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ vs2015编译json和protobuf报错nlohmann::detail::static_constnlohmann::detail::to_json_fn::value‘

    补充:这个问题也会导致protobuf编译和使用报错,按照本方法修复后问题解决 只要引入项目中的 #include “nlohmann/json.hpp” 用vs2015编译就会报错,甚至用vs2022的Visual Studio 2015 (v140)工具集编译也会报同样的错误,错误信息如下: 参考这篇博客“JSON for Modern C++ vs2015 企业版和专业

    2024年02月05日
    浏览(82)
  • 使用nlohmann json库进行序列化与反序列化

    nlohmann源码仓库:https://github.com/nlohmann/json 使用方式:将其nlohmann文件夹加入,包含其头文件json.hpp即可 demo

    2024年02月10日
    浏览(40)
  • nlohmann json:类型检查

    nlohmann提供了成员函数type(),用于返回当前的json数据类型: 可以根据type进行类型检查:

    2024年02月13日
    浏览(36)
  • 【程序员必备】UE4 C++ 虚幻引擎:详解JSON文件读、写、解析,打造高效开发!

    🙋‍♂️ 作者:海码007 📜 专栏:UE虚幻引擎专栏 💥 标题:【程序员必备】UE4 C++ 虚幻引擎:详解JSON文件读、写、解析,打造高效开发! ❣️ 寄语:人生的意义或许可以发挥自己全部的潜力,所以加油吧! 🎈 最后: 文章作者技术和水平有限,如果文中出现错误,希望大

    2024年02月03日
    浏览(57)
  • nlohmann json:通过items遍历object/array

    编译运行输出: key: one, value: 1 key: two, value: 2 key: 0, value: 1 key: 1, value: 2 key: 2, value: 4 key: 3, value: 8 key: 4, value: 16  可以看到对于object可以通过key()和value()拿到键值对 对

    2024年02月13日
    浏览(46)
  • nlohmann json:实现map和struct的互转

    可以借助json实现map和struct的互转:

    2024年02月11日
    浏览(45)
  • nlohmann::json 超简单序列化反序列化

    2024年01月20日
    浏览(40)
  • Unity解析json文件(分为json与jsonArray)

    什么是json? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度, 那么,JSON到底是什么? JSON就是一串字符串 只不过元素会使用特定的符号标注。 {} 双括号表示对象 [] 中括号表示数组 “” 双引号内是

    2024年02月08日
    浏览(42)
  • Spark解析JSON文件,写入hdfs

    一、用Sparkcontext读入文件,map逐行用Gson解析,输出转成一个caseclass类,填充各字段,输出。 解析JSON这里没有什么问题。 RDD覆盖写的时候碰到了一些问题 : 1.直接saveAsTextFile没有覆盖true参数; 2.转dataframe时,还得一个一个字段显化才能转成dataframe; 3.write时,一开始打算写

    2024年01月23日
    浏览(41)
  • 【python模块】python解析json文件详解

    JSON(Java Script Object Notation)是一种通常用于以不会“对系统造成负担”的方式传输数据(主要通过 API)的格式。基本原理是利用文本来记录数据点,并将数据点传输给第三方。 JSON是一种使用文本存储数据对象的格式。换句话说,它是一种数据结构,将对象用 文本形式 表示出

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包