菜鸟笔记
提升您的技术认知

【c 】使用 nlohmann 解析 json 文件-ag真人游戏

nlohmann 是德国工程师,以其名字为工程名的 nlohmann/json 项目又被成为 json for modern c 。
网上常见如何使用 nlohmann 生成 json 文件的中英文资料。但如何使用 nlohmann 解析 json 文件的 资料 不多,或者,不够清楚直接。
其实,工程的 readme.md 写得也算清楚。但是对于从未接触过 json 文件的新手来说,还是不太友好。此篇主要向未接触过 json 文件的新手介绍如何快速使用 nlohmann 解析 json 文件。

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

如果 json 文件够简单,如下,

{
  
	"pi":3.1415,
	"happy":true
}

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

#include "json.hpp"
#include 
#include 
using namespace std;
using json = nlohmann::json;
int main() {
  
	json j;			// 创建 json 对象
	ifstream jfile("test.json");
	jfile >> j;		// 以文件流形式读取 json 文件
	float pi = j.at("pi");
	bool happy = j.at("happy");
	return 0;
}

一般来说,json 文件包含很多的层级,转换成 c 则是结构体。以下 json 文件为例:

{
  
  "output": {
  
    "width": 720,
    "height": 1080,
    "framerate": 20,
    "crf": 31
  },
  "tracks": [
    {
  
      "name": "t1",
      "pieces": [
        {
  
          "file": "x.mp4",
          "starttime": 2,
          "endtime": 6
        },
        {
  
          "file": "y.mp4",
          "starttime": 9,
          "endtime": 13
        }
      ]
    },
    {
  
      "name": "t2",
      "pieces": [
        {
  
          "file": "z.mp4",
          "starttime": 0,
          "endtime": 10
        }
      ]
    }
  ]
}

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

struct video_info {
  
	int width;
	int height;
	int frame_rate;
	int crf;
}

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

    struct pieceinfo {
  
        string  pathname;
        int     starttime;
        int     endtime;
    };
    struct trackinfo {
  
        string      name;
        pieceinfo   pieces[10];
        int         size;   // piceces 大小
    };

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

#include "json.hpp"
#include 
#include 
using namespace std;
using json = nlohmann::json;
namespace jsonns {
  
    struct videoinfo {
  
        int width;
        int height;
        int framerate;
        int crf;
    };
    void from_json(const json& j, videoinfo& v) {
  
        j.at("width").get_to(v.width);
        j.at("height").get_to(v.height);
        j.at("framerate").get_to(v.framerate);
        j.at("crf").get_to(v.crf);
    }
    struct pieceinfo {
  
        string  pathname;
        int     starttime;
        int     endtime;
    };
    
    void from_json(const json&j, pieceinfo &p) {
  
        j.at("file").get_to(p.pathname);
        j.at("starttime").get_to(p.starttime);
        j.at("endtime").get_to(p.endtime);
    }
    struct trackinfo {
  
        string      name;
        pieceinfo   pieces[10];
        int         size;
    };
    void from_json(const json&j, trackinfo &t) {
  
        j.at("name").get_to(t.name);
        for(int i = 0; i < j["pieces"].size(); i  ) {
  
            t.pieces[i] = j["pieces"][i];
        }
        t.size = j["pieces"].size();
    }
}
int main()
{
  
    json j;
    ifstream jfile("test.json");
    jfile >> j;
    jsonns::videoinfo vi = j.at("output");
    int tilength = j["tracks"].size();
    jsonns::trackinfo ti[tilength];
    for (int i = 0; i < tilength; i  ) {
  
        ti[i] = j["tracks"][i];
    }
    return 0;
}
网站地图