当前位置:   article > 正文

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

nlohmann

一、前言

以前更多使用 Qt5 专门的 QJsonDocument 及其相关类来读写 JSON 文档,但用久了发现比较麻烦,不够简洁美观,所以更换使用 nlohmann。

nlohmann 是一个用于解析 JSON 的开源 C++ 库,口碑一流,使用非常方便直观,是很多 C++ 程序员的首选

nlohmann - Readme处有详细说明用法,但篇幅过长,不便于迅速阅读抓重点。而且,所举例的某些用法实践上其实比较少用到,而某些实践上常用到的一些用法,官网却缺例子。所以这里简要总结了一下它的主要用法,并加上几个示例,希望能帮助刚接触的同学快速用上。

nlohmann 是德国工程师,以其名字为工程名的 nlohmann/json 项目又被成为 JSON for Modern C++。
 

工程引用
nlohmann 使用了 hpp,这种形式被称为 header only。在自己的工程中使用 nlohmann 时,仅需 #include “json.hpp” 即可。在所有 #include 之后,再添加一句 using json = nlohmann::json 会更加便捷。

简单文件解析
如果 JSON 文件够简单,如下,

  1. {
  2.     "pi":3.1415,
  3.     "happy":true
  4. }


不包括任何结构体或数组,则解析代码如下:

  1. #include "json.hpp"
  2. #include <fstream>
  3. #include <iostream>
  4. using namespace std;
  5. using json = nlohmann::json;
  6. int main() {
  7.     json j;            // 创建 json 对象
  8.     ifstream jfile("test.json");
  9.     jfile >> j;        // 以文件流形式读取 json 文件
  10.     float pi = j.at("pi");
  11.     bool happy = j.at("happy");
  12.     return 0;
  13. }

较复杂的 JSON 文件解析
一般来说,JSON 文件包含很多的层级,转换成 C++ 则是结构体。以下 json 文件为例:

  1. {
  2. "output": {
  3. "width": 720,
  4. "height": 1080,
  5. "frameRate": 20,
  6. "crf": 31
  7. },
  8. "tracks": [
  9. {
  10. "name": "t1",
  11. "pieces": [
  12. {
  13. "file": "x.mp4",
  14. "startTime": 2,
  15. "endTime": 6
  16. },
  17. {
  18. "file": "y.mp4",
  19. "startTime": 9,
  20. "endTime": 13
  21. }
  22. ]
  23. },
  24. {
  25. "name": "t2",
  26. "pieces": [
  27. {
  28. "file": "z.mp4",
  29. "startTime": 0,
  30. "endTime": 10
  31. }
  32. ]
  33. }
  34. ]
  35. }


从这个 json 文件,人脑解析的话,我们可以看到,它包括两大部分 "output" 和 "tracks"。其中,output 可以用结构体来表示,其代码如下:

  1. struct video_info {
  2.     int width;
  3.     int height;
  4.     int frame_rate;
  5.     int crf;
  6. }

而另一部分可看作是有两个元素的结构体 "tracks" 的数组,其结构体包括 string 的 name,和另一个结构体 "pieces" 的数组。用 C++ 代码可表示为如下:

  1.     struct pieceinfo {
  2.         string  pathname;
  3.         int     startTime;
  4.         int     endTime;
  5.     };
  6.     struct trackinfo {
  7.         string      name;
  8.         pieceinfo   pieces[10];
  9.         int         size;   // piceces 大小
  10.     };

为了解析结构体类内容,需要定义对结构体的解析方法。因此,整个解析过程如下:

  1. #include "json.hpp"
  2. #include <iostream>
  3. #include <fstream>
  4. using namespace std;
  5. using json = nlohmann::json;
  6. namespace jsonns {
  7.     struct videoinfo {
  8.         int width;
  9.         int height;
  10.         int frameRate;
  11.         int crf;
  12.     };
  13.     void from_json(const json& j, videoinfo& v) {
  14.         j.at("width").get_to(v.width);
  15.         j.at("height").get_to(v.height);
  16.         j.at("frameRate").get_to(v.frameRate);
  17.         j.at("crf").get_to(v.crf);
  18.     }
  19.     struct pieceinfo {
  20.         string  pathname;
  21.         int     startTime;
  22.         int     endTime;
  23.     };
  24.     
  25.     void from_json(const json&j, pieceinfo &p) {
  26.         j.at("file").get_to(p.pathname);
  27.         j.at("startTime").get_to(p.startTime);
  28.         j.at("endTime").get_to(p.endTime);
  29.     }
  30.     struct trackinfo {
  31.         string      name;
  32.         pieceinfo   pieces[10];
  33.         int         size;
  34.     };
  35.     void from_json(const json&j, trackinfo &t) {
  36.         j.at("name").get_to(t.name);
  37.         for(int i = 0; i < j["pieces"].size(); i++) {
  38.             t.pieces[i] = j["pieces"][i];
  39.         }
  40.         t.size = j["pieces"].size();
  41.     }
  42. }
  43. int main()
  44. {
  45.     json j;
  46.     ifstream jfile("test.json");
  47.     jfile >> j;
  48.     jsonns::videoinfo vi = j.at("output");
  49.     int tilength = j["tracks"].size();
  50.     jsonns::trackinfo ti[tilength];
  51.     for (int i = 0; i < tilength; i++) {
  52.         ti[i] = j["tracks"][i];
  53.     }
  54.     return 0;
  55. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/553862
推荐阅读
相关标签
  

闽ICP备14008679号