nlohmann::json概述与基础用法

DinS          Written on 2017/11/3

I don’t know who is the king of kings.
But I do know nlohmann::json is the data-structure of data-structures
此数据结构一出,简直是惊天地泣鬼神,有如下的好处:
现代风格,代码简洁;
万能型数据结构(装载任何类型的数据,包括自定义数据);
蕴含OO思想,可以作为OO数据库使用;
到底有没有这么好,读完本专题你就知道了。

一、JSON概述

JSON全称是JavaScript Object Notation,从名字可以看出来发源于JavaScript。
其用意是制作一种良好的数据交换格式,既方便人阅读又方便计算机解析。这个目标确实做到了,到目前为止JSON大概算最受欢迎的数据交换格式,在各种编程语言之间都可以轻松交换数据。另一种用于该目的的格式是xml。

关于JSON的详细格式可以参考官网,也是十分简短的,这里就举几个例子帮助理解。

最重要的概念是object,用{}括起来表示一个object。所有JSON一头一尾都是{和},说明整个JSON都是一个object。在object里面可以存放多种数据格式,统称member。
最最常见的是key/value对,其中key是string类型,需要用””括起来。value可以是任何常见的类型,比如int,bool,string,null指针。每个member之间用,分隔。
value里还可以嵌套放置object。
value还可以是数组,用[]括起来,每一个值用,分隔。
上图中最后一个value是一个object,object内部有两个member。

可以看出来JSON整体呈现一种层次结构
各个member之间的顺序并不重要。

了解了JSON之后遇到的问题就是如何解析、输出JSON,这个不需要自己写了,有许多优秀的库来做这件事。

二、配置json for modern c++(即nlohmann::json)

这里介绍json for modern c++库。
第一个问题就是为什么使用这个库
原因:
1.现代C++风格,语法直观,使用简便
2.没有复杂的编译、依赖关系,直接包含头文件即可
缺点:
1.并非最快的JSON库
2.内存占用大一点

之所以推荐这个库主要是看中了现代C++风格,这会增加开发效率,那几个缺点其实并无大碍,硬件发展的比软件要快很多。还有就是看中了万能型数据结构。

先来说说配置环境,其实根本不需要配置。
去https://github.com/nlohmann/json下载压缩包,解压出来是这样。

其他的不用管,(doc里有例子可以看一下)直接进入src文件夹,就一个文件

新建工程,再建一个文件夹,把那个json.hpp放入即可

然后设置工程属性

指定刚才的文件夹,这样包含头文件就可以找到了。
甚至都可以不要这一步,直接#include”json/json.hpp”即可。
代码中这样写:

就可以使用了。

因为只是一个hpp文件,所以不需要编译过程,配置起来非常方便。

三、基础使用方法

下面介绍这个库的基础操作,看了这些你就会明白为什么叫做现代C++风格

1.插入普通member

很清晰明了,直接使用[]插入key,后面跟value,这个用法与map很相似。
另外跟cout配合确实很人性化,输出结果:

2.插入复杂memeber

点这里看大图

对于数组,可以用初始化列表
对于嵌套object,可以有两种写法
第一种是连续n个[],另一种还是借助初始化列表
比较起来还是前者更加灵活,只要这样理解即可:n个[]代表深入了n层

运行结果:

应该注意到在插入member的时候我们没有指定value的类型,这个会自动推断出来。

3.获取value

看了下面的代码就知道为什么叫现代C++了,因为设计跟STL一致

三种方式,就是个map。
最安全的是find,但代码书写最麻烦
at简便许多,也能够告知是否存在key
[]最简单,不过也最容易出现意外
当然对于嵌套object还是用[]最直观
如果使用auto则得不到value的值,而是一个类似object的东西,这其实也说明了[]返回的到底是什么东西,以及为什么可以不断[]逐层深入。

从获取value也可以知道一件事:如果不知道JSON的结构则根本无法解析JSON

四、格式化JSON

处理JSON最常见的一种情况是网络上传过来一个JSON串或者有一个JSON文件,需要从中提取出相应信息,然后继续计算。对于这种情况json for modern c++提供了非常简便的方法。

点击这里看大图

只要使用命名空间里面的parse函数即可,运行结果:

如果传入的字符串不符合JSON规范呢?
会抛出parse_error异常,记得使用时配合try-catch。

点击这里看大图

结果:

可以定位到具体的错误位置。

还有一点要说明,网络传输JSON通常都是UTF8编码,这个情况json for modern c++是可以处理的,得益于UTF8可以放到string里面,所以解析起来其实是一样的。另外如果value是二进制也没有关系,一样放到string里解析即可。

去格式化JSON就更简单了,直接用dump即可。

输出结果:

以上就是nlohmann::json的基础用法,其实任何json库都支持这些功能,没什么大不了的,但是接下来的是只有nlohmann::json才能做到的《nlohmann::json万能数据结构》。