CJSON


CJSON 开发详情与使用教程

github

开发灵感

考研学烦了于是想着重新将之前写的游戏引擎实现一遍,其间需要用到json解析的库,想到自己之前使用c实现过一个json解析库,遂以c++重写而成此库。

再写json库的时候最大的难度在于如何设计接口。经过调查他人的json库以及结合自己对json解析的需求选择了使用
**[],(),-,{}**来进行操作。这样再增加可读性的同时还可以增强我对c++的认知。

使用

首先下载json.hpp,将这个文件单独添加进你的项目中。

more

开发介绍。

两个数据结构

  1. JSON_DATA
  2. JSON

JSON_DATA

JSON_DATA是一个结构体,其负责存放一个json数据。json的重点在于如何将json的数据进行良好的组织来增强易用性。JSON_DATA可以使用初始化列表进行构建,即使用**{}**的形式,但你没有必要直接使用JSON_DATA,因为关于JSON_DATA的操作时隐性的,你可以通过 Operator 来进行一切你想要的操作。

JSON数据分为如下的类型:

1
2
3
4
5
6
7
JSON_TYPE_NULL,
JSON_TYPE_TRUE,
JSON_TYPE_FALSE,
JSON_TYPE_NUMBER,
JSON_TYPE_ARRAY,
JSON_TYPE_STRING,
JSON_TYPE_OBJECT

JSON_DATA默认初始化的type为JSON_TYPE_NULL。你可以使用如下的方式将其初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct JSON_DATA Json_data
Json_data jd = { 1,2,3 };
jd.print_data();
jd = { "key", true};
jd.print_data();
jd = { "key", nullptr };
jd.print_data();
jd = { "key", 111.0 };
jd.print_data();
jd = { "key", "string" };
jd.print_data();
jd = { "key", {1,2,3} };
jd.print_data();
jd = { {"key1", {1,2,3}},{"key2",true}};
jd.print_data();

JSON

  1. 解析
1
2
3
JSON::Json js;
//解析
js.parse("test.json");
  1. 获取操作句柄
1
JSON::Operator& op = js.get_operator();
  1. 读取数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//获取string
std::cout << op["name"].get_string() << std::endl;;
//获取bool
if (op["bool"].get_bool())
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
//获取null
if (op["null"].is_null())
std::cout << "this is a null" << std::endl;
else
std::cout << "this is not a null" << std::endl;
//获取number
std::cout << op["number"].get_number() << std::endl;
//获取数组 只支持全部为double的数组
for (double i : op["array_double"].get_array_double())
std::cout << i << std::endl;
//获取数组中的某元素 使用索引
std::cout << op["array"][1].get_string() << std::endl;
  1. 写入数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//测试进行写入
//使用 () 代表代表进行写入,此时可以对json进行增改查
op("pi") = 3.14;
op("happy") = true;
op("name") = "niels";
op("nothing") = (void*)nullptr;
op("answer") = {"everything",42.0} ;

//将初始化列表先解析为 Json_data 再以Json_data为初始化参数
op("array") = { 1,2,3 };
//加入新值
op("array")(3) = 4.0;
//修改值
op("array")(1) = 5.0;
//直接修改数组
op("array") = { 1,2,3 };
//数组添加任意类型数据
op("array")(1) = nullptr;
op("array")(2) = true;
op("array")(3) = false;
op("array")(4) = (double)100;
op("array")(5) = "string";
//数组也可以当作数组添加进去
op("array")(1) = { 1,2,3 };
//同理可修改这个数组的值 有时候会编译器会将搞不清,所以最好自己显式地表示出来
op("array")(1)((unsigned int)0) = (double)99;
op("array")(1)((unsigned int)1) = true;
op("array")(1)((unsigned int)2) = "array in array";
op("array")(1)((unsigned int)5) = "array in array";
//数组中的对象
// 生成一个键值对
op("array")(1) = { "1",1.0 };
op("array")(2) = { "2",true };
op("array")(1) = { {"1",1.0}, {"2",true},{"3",nullptr},{"4","string"} };
//嵌套
op("array")(1)("1") = { {"1 in 1",1.0}, {"2",true},{"3",nullptr},{"4","string"},{"5",{1,2,3,4}} };
//修改
op("array")(1)("1")("1 in 1") = "1 in 1 的值变为了 9.0";
//覆盖
//op("array")(1)("1") = { 1,2,3,4 };
//覆盖
//op("array") = (void*) nullptr;

//object
op("object") = { {"obj_1",1.0},{"obj_2",(void*)nullptr},{"obj_3",true},{"obj_4","this is obj_4"},{"obj_5",{1.0,2.0,3.0,4.0}} };

//删除某一个对象中的某一个键值对 object::obj_1
op ("object")-("obj_1");
//删除根对象上的object键值对
//op - ("object");

//删除数组元素 0 为索引
op("object")("obj_5") - (0);
op("object")("obj_5") - (0);
op("object")("obj_5") - (0);
op("object")("obj_5") - (0);
  1. 字符串化
1
2
3
4
5
6
js.stringify("set_value.json");
//stringify有两种重载
//直接写入文件
void stringify(const char* path);
//将传入的json数据写入str.倘若root为null则使用js自身的root.
void stringify(std::string& str,Json_data* root);

文章作者: 崔文耀
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 崔文耀 !
  目录