赞
踩
以前更多使用 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 文件够简单,如下,
- {
- "pi":3.1415,
- "happy":true
- }
不包括任何结构体或数组,则解析代码如下:
- #include "json.hpp"
- #include <fstream>
- #include <iostream>
- 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 文件解析
一般来说,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" 的数组,其结构体包括 string 的 name,和另一个结构体 "pieces" 的数组。用 C++ 代码可表示为如下:
- struct pieceinfo {
- string pathname;
- int startTime;
- int endTime;
- };
- struct trackinfo {
- string name;
- pieceinfo pieces[10];
- int size; // piceces 大小
- };
为了解析结构体类内容,需要定义对结构体的解析方法。因此,整个解析过程如下:
- #include "json.hpp"
- #include <iostream>
- #include <fstream>
-
- 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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。