【C++】一个极简单且强大的JSON操作库

今天再介绍一个用于C++操作JSON的库,以前也介绍过相关库,不过使用上稍微的复杂一点,如果常写JS的话,就知道js操作JSON相当的方便

其实C++也有一个操作JSON非常方便强大库

JSON for Modern C++

这个库的使用基本不比JS操作JSON复杂多少,最大的亮点就是不需要依赖,只有一个单文件,文件只有800多K,使用的时候直接加入到你的项目一起编译就行

注:以下代码在cygwin gcc 11.3中调试通过

基本使用

从它的仓库下载到源码后,把single_include/nlohmann/json.hpp,放到你的项目里,在要用的文件里引入这个文件,然后用using 使用这个json类。

下面演示一个最简单的json操作过程

#include "json.hpp"
using json = nlohmann::json;
json object = {{"a", 1}, {"b", 2}};
cout<<"object:"<<object<<endl;
object["c"]=3;
cout<<"object.c:"<<object["c"]<<endl;

输出如下

object:{"a":1,"b":2}
object.c:4

这是一个最简单使用操作方式,第3行,是创建了一个json对象,里面有a,b两个属性,值分别是1,2。这个类似用js创建了对象

let object = {"a":1, "b":2};

第5行,是给这个对象创建一个c属性,它的值是3,这个操作方式js里一样了,如果不存在c属性的话,就给他创建一个,如果有的话,就把他的值更新成最新的

从实际使用出发

上面的代码只是用于演示如何使用,事实上,在实际开发中,大多数不可能出现自己定义json,然后给自己使用的场景,多数还是要解析外来的json或者在程序中生成json给外部使用

从字符串解析

从字符串解析,使用parse函数。假设调用了一个远处的API返回了如下text变量定义的内容

   string text = R"(
    {
        "Code":1,
        "Message":2,
        "Data": [{
            "a":1,
            "b":2,
            "c":3
        },{
            "a":4,
            "b":5,
            "c":6
        }]
    }
   )";
   json strjson = json::parse(text);   
   std::cout << "Code:"<<strjson["Code"]<< ",Message:"<<strjson["Message"]<<endl ;
   nlohmann::basic_json v = strjson["Data"];
   for (nlohmann::basic_json i : v)
   {
        std::cout << "a:" << i["a"]<< ",b:"<<i["b"]<<",c:"<<i["c"]<<endl ;
   }

第16行,是从一个从字符串创建json对象,第17行是读取Code,Message的内容,第18行是读取Data的内容,并把它赋值给v,因为Data是数组类型,所以,可以使用循环,读取数组内的每个元素的内容,每个元素类型都是basic_json类型,然后使用[]读取每个属性

输出内容如下

Code:1,Message:2
a:1,b:2,c:3
a:4,b:5,c:6

输出字符串

如果你在程序中创建个json类,想给其他程序使用的话,就可以输出字符串,这个很简单,使用to_string()方法

json j = {{"one", 1}, {"two", 2}};
string s = to_string(j);
cout<<s<<endl;

输出如下

{"one":1,"two":2}

主要的一些使用方法

遍历key,value

在JS中,可以使用for in 或者Object.getOwnPropertyNames输出对象的key,value.在本库中也可以输出,举例如下

json object = {{"a", 1}, {"b", 2}};
for (auto it = object.begin(); it != object.end(); ++it)
{
     cout << "key: " << it.key() << ", value:" << it.value() << endl;
}

输出如下

key: a, value:1
key: b, value:2

增加属性

除了第一个例子里增加属性的方式

object["c"]=3;

还可增加更深层的属性,比如

json object = {{"a", 1}, {"b", 2}};
object["c"]["d"]["tt"] = {2,3};
cout<<"object:"<<object<<endl;

输出如下

object:{"a":1,"b":2,"c":{"d":{"tt":[2,3]}}}

应为库本身重写了很多操作符,还以使用符号’+'来搞,用加号重写上面的代码

   json object = {{"a", 1}, {"b", 2}};
   object+={"c",{{"d",{{"tt",{2,3}}}}}};
   cout<<"object:"<<object<<endl;

输出如下,和上面效果一样

object:{"a":1,"b":2,"c":{"d":{"tt":[2,3]}}}

但是这里要注意一点
创建属性一定要在属性外面多套一层花括号,否则它就被解析成数组了,例如上栗,如果d,c外没有多一层花括号,c,d最终就被解析成数组了,代码如下

json object = {{"a", 1}, {"b", 2}};
object+={"c",{"d",{"tt",{2,3}}}};
cout<<"object:"<<object<<endl;

输出如下

object:{"a":1,"b":2,"c":["d",["tt",[2,3]]]}

错误处理

这个常用的场景可能是解析外来的json时候报错,可以使用try,catch捕获错误,然后用parse_error输出错误

try
 {
     json::parse("{\"a\",}");
 }
 catch (json::parse_error& e)
 {
     std::cout << e.what() << endl;
 }

本例将输出错误信息

[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing object separator - unexpected ','; expected ':'

删除属性

比如,有些属性需要再加工以后使用,要增加一些属性,或者删除一些属性,在此库中,可以使用erase方法删除属性,例如,从object 中把fg属性删掉

 json object = {{"a", 1}, {"b", {{"f",{3,4}},{"fg",{3,4}}}}};
 object["b"].erase("fg");
 cout<<object<<endl;

输出如下

{"a":1,"b":{"f":[3,4]}}

使用erase的时候,参数是属性名,前面要一直指向他的父属性
例如,有如下json

 json object = {{"a", 1}, {"b", 2},{"c",{{"d",{{"tt",{2,3}}}}}}};

如果要删除tt属性

 json object = {{"a", 1}, {"b", 2},{"c",{{"d",{{"tt",{2,3}}}}}}};
 object["c"]["d"].erase("tt");
 cout<<object<<endl;

输出如下

{"a":1,"b":2,"c":{"d":{}}}

其他的一些使用方法

数据类型判断

is_array :是否为数组
is_boolean:是否为bool值
is_null:是否为空
is_number:是否为数字
is_object:是否为object
is_string:是否字符串

举例如下

   json object = {{"a", 1}, {"b", "b"}};
   cout<<object["a"].is_string()<<endl;
   cout<<object["a"].is_number()<<endl;
   cout<<object["b"].is_number()<<endl;
   cout<<object["b"].is_string()<<endl;

输出如下

0
1
0
1

查找属性

查找某个属性的值,可以使用find,举例如下,从object 中找到tt属性的值

json object = {{"a", 1}, {"b", 2},{"c",{{"d",{{"tt",{2,3}}}}}}};
cout<< *object["c"]["d"].find("tt") <<endl;

输出如下

[2,3]

使用的时候,要从被找的属性的父属性上查找,不能从根上找,那样找不到,如果上例改为

json object = {{"a", 1}, {"b", 2},{"c",{{"d",{{"tt",{2,3}}}}}}};
cout<< *object.find("tt") <<endl;

这样就报错了

统计属性数量

使用size方法,可以统计出,父属性下有多少个子属性

json object = {{"a", 1}, {"b", 2},{"c",{{"d",{{"tt",{2,3}}}}}}};
cout<< object.size() <<endl;
cout<< object["c"]["d"].size() <<endl;

输出如下

3
1

以上就是关于JSON for Modern C++的基本介绍,其它的方法还有很多,本文只例举了几个可能常用的方法

你可能感兴趣的:(C++,json,c++,javascript)