C++解析和构建json(cjson使用手册)

ops/2024/11/15 5:15:06/

C++解析和构建json【cjson使用手册】

  • 一、cjson下载
  • 二、cjson工程使用
    • 2.1 静态库使用
    • 2.1 源码使用(推荐)
  • 三、cjson详解
    • 3.1 解析json字符串
      • 3.1.1 解析对象
      • 3.1.2 解析数组:方法一(获取列表数量然后按照位置获取)
      • 3.1.2 解析数组:方法二(使用foreach遍历)
      • 3.1.3 解析对象包含数组
      • 3.1.4 解析数组对象
    • 3.2 json结构体构建
      • 3.2.1 构建对象
      • 3.2.2 构建数组
      • 3.2.3 构建对象中包含数组
      • 3.2.4 构建数组中包含对象
    • 3.3 json类型判断
      • 1. `cJSON_IsInvalid`
      • 2. `cJSON_IsFalse`
      • 3. `cJSON_IsTrue`
      • 4. `cJSON_IsBool`
      • 5. `cJSON_IsNull`
      • 6. `cJSON_IsNumber`
      • 7. `cJSON_IsString`
      • 8. `cJSON_IsArray`
      • 9. `cJSON_IsObject`
      • 10. `cJSON_IsRaw`
  • 四、源码地址

json_1">一、cjson下载

  • 国外:github下载
    https://github.com/DaveGamble/cJSON
    在这里插入图片描述

  • 国内:gicode下载
    https://gitcode.com/gh_mirrors/cj/cJSON/overview
    在这里插入图片描述

json_10">二、cjson工程使用

2.1 静态库使用

将cjson作为静态库使用。

  • 1.构建cjson静态库
    构建静态库就是将cjson作为静态库使用,其实和源码使用没有太大的区别。
    构建CMakeLists.txt
cmake_minimum_required( VERSION 3.10 )
project(cjson)add_library(${PROJECT_NAME} cjson.c cjson.h)install(TARGETS ${PROJECT_NAME}  DESTINATION lib)
install(FILES ${PROJECT_SOURCE_DIR}/cjson.h DESTINATION include)

使用qt编译。

  • 2.使用cjson静态库
    将编译的cjson.lib和cjson.h放在项目中的depend/cjson/中
    depend/cjson/lib/cjson.lib
    depend/cjson/include/cjson.h
    项目中指定库文件和头文件。分别任上面两个目录就可以了。

2.1 源码使用(推荐)

源码使用,比较简单。
直接将cjson.c和cjson.h放在源文件中一起编译就可以了。

json_34">三、cjson详解

json_35">3.1 解析json字符串

json解析的最终结果只有三种1. 字符串类型。2.整数。3.float。
整个字符串解析的关键函数为cJSON_Parse
公共函数说明
文件读取,传递文件名称获取文件内容。(因为json文件中的双引号比较麻烦输入,所以我直接将测试内容放在文件中读取这样比较方便。)

string ReadFile(string filePath){ifstream ifs(filePath);if(!ifs.is_open()){return "";}std::string line;std::string content;while (getline(ifs, line)) { // 逐行读取文件内容content+=line;}ifs.close(); // 关闭文件return content;
}

因为创建的对象不知道什么时候释放,因此我使用智能指针的方式,等到他不使用的时候自动释放。

struct cJSON_Deleter {void operator()(cJSON* json) const {cJSON_free(json);}
};

3.1.1 解析对象

样例一:

json">{"name":"三雷科技","age":100,"hight":124.5
}

解析代码如下:

void parse_object1(){string content = ReadFile("data/object1.txt");if(content.empty()){return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));if(json_data == nullptr){cout <<"解析失败!";}cJSON *json_name = cJSON_GetObjectItem(json_data.get(),"name");cJSON *json_age = cJSON_GetObjectItem(json_data.get(),"age");cJSON *json_hight = cJSON_GetObjectItem(json_data.get(),"hight");string name = json_name->valuestring;int age = json_age->valueint;double hight = json_hight->valuedouble;cout <<"name:"<<name<<endl;cout <<"age:"<<age<<endl;cout <<"hight:"<<hight<<endl;
}

json_data:为获取的json对象。
cJSON_GetObjectItem从对象中获取对象中的属性内容。根据关键词进行获取。
拿到该关键的json对象item以后再使用valuestring\valueint\valuedouble获取对应类型的值。

3.1.2 解析数组:方法一(获取列表数量然后按照位置获取)

样例一:

json">["apple","banana","Orange","watermelon"]

想获取列表的长度,然后按照位置进行获取。
cJSON_GetArraySize:该函数用于获取 JSON 数组的大小(即数组中的元素数量)。
cJSON_GetArrayItem:该函数用于获取 JSON 数组中的某个特定索引处的元素。

void parse_array1(){string content = ReadFile("data/array1.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));int len = cJSON_GetArraySize(json_data.get());for(int i = 0 ;i < len ; i++){cJSON *item = cJSON_GetArrayItem(json_data.get(),i);if(item){cout <<"item:"<<item->valuestring<<endl;}}
}

3.1.2 解析数组:方法二(使用foreach遍历)

样例一:

json">["apple","banana","Orange","watermelon"]

cJSON_ArrayForEach:遍历 cJSON 数组: cJSON_ArrayForEach 可以轻松遍历 cJSON 数组中的每一个元素,省去了手动获取数组大小和逐个索引访问元素的麻烦。

void parse_array2(){string content = ReadFile("data/array1.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));cJSON* item = nullptr;cJSON_ArrayForEach(item, json_data.get()) {if (cJSON_IsString(item)) {std::cout << "item: " << item->valuestring<< std::endl;}}
}

3.1.3 解析对象包含数组

案例:

json">{"fruit":["apple","banana","Orange","watermelon"],"unit":["one","two","three"]
}

需要分布解析,先解析对象然后在解析每个数组,需要一个一个的解析。

void parse_object_array(){string content = ReadFile("data/object_array.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));cJSON *json_fruit_array = cJSON_GetObjectItem(json_data.get(),"fruit");cJSON* item = nullptr;cJSON_ArrayForEach(item, json_fruit_array) {if (cJSON_IsString(item)) {std::cout << "fruit item: " << item->valuestring<< std::endl;}}cJSON *json_unit_array = cJSON_GetObjectItem(json_data.get(),"unit");cJSON_ArrayForEach(item, json_unit_array) {if (cJSON_IsString(item)) {std::cout << "unit item: " << item->valuestring<< std::endl;}}
}

运行结果
在这里插入图片描述

3.1.4 解析数组对象

案例 array_object.txt

json">{"students": [{"name": "Alice", "age": 21},{"name": "Bob", "age": 22},{"name": "Charlie", "age": 23}]
}
void parse_array_object(){string content = ReadFile("data/array_object.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));// 先获取students的jsoncJSON *json_student_array = cJSON_GetObjectItem(json_data.get(),"students");if(cJSON_IsNull( json_student_array)){cout<<"students 解析失败";return ;}if(cJSON_IsArray(json_student_array)){cJSON* item = nullptr;cJSON_ArrayForEach(item,json_student_array){cJSON* json_item_name = cJSON_GetObjectItem(item,"name");cJSON* json_item_age = cJSON_GetObjectItem(item,"age");if(json_item_name){std::cout <<"name:"<<json_item_name->valuestring;}if(json_item_age){std::cout <<",age:"<<json_item_age->valueint;}std::cout << std::endl;}}
}

运行结果
在这里插入图片描述

json_226">3.2 json结构体构建

构建好的json结构体可以通过cJSON_Print获取json结构对应的字符串。

3.2.1 构建对象

3.2.2 构建数组

  • 构建整形数组
    cJSON_CreateIntArray:
void CreateIntArray(){int num[] = {10,4,5,6,1};cJSON *json_int_array = cJSON_CreateIntArray(num,sizeof(num));std::cout << cJSON_Print(json_int_array)<<std::endl;;cJSON_Delete(json_int_array );
}

在这里插入图片描述

  • 构建float数组
    cJSON_CreateFloatArray:
void CreateFloatArray(){float num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateFloatArray(num,sizeof(num));std::cout << cJSON_Print(json_float_array)<<std::endl;;cJSON_Delete(json_float_array );
}

在这里插入图片描述

  • 构建Double数组
    cJSON_CreateDoubleArray:
void CreateDoubleArray(){double num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateDoubleArray(num,sizeof(num));std::cout << cJSON_Print(json_float_array)<<std::endl;;cJSON_Delete(json_float_array );
}

在这里插入图片描述

  • 构建字符串数组
    cJSON_CreateStringArray:
void CreateDoubleArray(){const char *string[] = {    "Hello",    "World",    "I",    "Am",    "Programmer"};cJSON *json_string_array = cJSON_CreateDoubleArray(string,sizeof(string)/sizeof(string[0]));std::cout << cJSON_Print(json_string_array)<<std::endl;;cJSON_Delete(json_string_array);
}

在这里插入图片描述

  • 构建任意类型数组
void CreateArray(){cJSON *cjson_array = cJSON_CreateArray();cJSON *cjson_number = cJSON_CreateNumber(10);cJSON *cjson_bool = cJSON_CreateBool(false);cJSON *cjson_string = cJSON_CreateString("name");cJSON_AddItemToArray(cjson_array,cjson_number);cJSON_AddItemToArray(cjson_array,cjson_bool );cJSON_AddItemToArray(cjson_array,cjson_string );std::cout <<cJSON_Print(json_array)<<std::endl;cJSON_Delete(cjson_array);
}

3.2.3 构建对象中包含数组

void CreateObejectArray(){std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_CreateObject());const  char *string[] = {    "Hello",    "World",    "I",    "Am",    "Programmer"};cJSON *json_string_array = cJSON_CreateStringArray(string,sizeof(string)/sizeof(string[0]));double num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateDoubleArray(num,sizeof(num)/sizeof (double));cJSON_AddItemToObject(json_data.get(),"word",json_string_array );cJSON_AddItemToObject(json_data.get(),"number",json_float_array );std::cout  <<cJSON_Print(json_data.get())<<std::endl;
}

cJSON_AddItemToObeject:创建一个item添加到一个对象中,参数为:
json_object:json对象
string : 关键词
json_item:对象的值
在这里插入图片描述

3.2.4 构建数组中包含对象

struct Student{Student(std::string name ,int age ,std::string sex){this->name = name;this->age = age;this->sex = sex;}std::string name;int age;std::string sex;
};
void CreateArrayObeject(){std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_CreateArray());std::vector<Student> vstu;Student stu1("zhangsan",10,"nan");Student stu2("lisi",12,"nan");Student stu3("wangwu",13,"nv");vstu.push_back(stu1);vstu.push_back(stu2);vstu.push_back(stu3);for(auto stu :vstu){cJSON *item = cJSON_CreateObject();cJSON_AddItemToObject(item ,"name",cJSON_CreateString(stu.name.c_str()));cJSON_AddItemToObject(item ,"age",cJSON_CreateNumber(stu.age));cJSON_AddItemToObject(item ,"sex",cJSON_CreateString(stu.sex.c_str()));cJSON_AddItemToArray(json_data.get(),item);}std::cout  <<cJSON_Print(json_data.get())<<std::endl;
}

运行结果:
在这里插入图片描述

json_345">3.3 json类型判断

cJSON 库提供了一组宏,用于检查 cJSON 对象的类型。这些宏使得在处理 JSON 数据时,可以轻松地判断 JSON 对象的类型,并根据类型进行相应的处理。以下是这些宏的详细说明:

1. cJSON_IsInvalid

功能: 判断 cJSON 对象是否是无效的(类型为 cJSON_Invalid)。
使用场景: 在处理 JSON 解析结果时,用于检查对象是否无效或未初始化。

2. cJSON_IsFalse

功能: 判断 cJSON 对象是否为布尔值 false(即类型为 cJSON_False)。
使用场景: 用于检测 JSON 布尔值 false

3. cJSON_IsTrue

功能: 判断 cJSON 对象是否为布尔值 true(即类型为 cJSON_True)。
使用场景: 用于检测 JSON 布尔值 true

4. cJSON_IsBool

功能: 判断 cJSON 对象是否为布尔类型(即类型为 cJSON_TruecJSON_False)。
使用场景: 用于检测 JSON 布尔类型的值,不论是 true 还是 false

5. cJSON_IsNull

功能: 判断 cJSON 对象是否为 null(即类型为 cJSON_NULL)。
使用场景: 用于检测 JSON 中的 null 值。

6. cJSON_IsNumber

功能: 判断 cJSON 对象是否为数字(即类型为 cJSON_Number)。
使用场景: 用于检测 JSON 中的数字类型。

7. cJSON_IsString

功能: 判断 cJSON 对象是否为字符串(即类型为 cJSON_String)。
使用场景: 用于检测 JSON 中的字符串类型。

8. cJSON_IsArray

功能: 判断 cJSON 对象是否为数组(即类型为 cJSON_Array)。
使用场景: 用于检测 JSON 中的数组类型。

9. cJSON_IsObject

功能: 判断 cJSON 对象是否为对象(即类型为 cJSON_Object)。
使用场景: 用于检测 JSON 中的对象类型。

10. cJSON_IsRaw

功能: 判断 cJSON 对象是否为原始未处理的 JSON 数据(即类型为 cJSON_Raw)。
使用场景: 用于检测未被处理的原始 JSON 数据,通常用在需要处理 JSON 内嵌代码或未解析的文本时。

四、源码地址

git源码
https://gitcode.net/arv002/qt/-/tree/master/c%2B%2B/cjson
csdn源码

https://download.csdn.net/download/arv002/89633210


http://www.ppmy.cn/ops/93271.html

相关文章

《Kotlin核心编程》2021版复习记录

目录 0 前言1 基础语法1.1 数据类型1.2 数组1.3 集合1.4 遍历数据和集合1.5 函数声明返回值类型1.6 var 和 val 2 高阶函数和lambda表达式2.1 高阶函数2.2 方法和成员引用2.3 链式调用2.4 扩展函数2.5 面向表达式编程2.5.1 when表达式2.5.2 for循环2.5.3 in 2.6 字符串相等 3 面…

PixelLib图像分割

文章目录 前言一、PixelLib依赖安装二、实例模型训练 前言 图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。 传统的图像分割方法主要分以下几类&#xff1a;基于阈值的分割方法、基于区域的分割…

【MySQL】事务——事务隔离等级、隔离级别、查看与设置隔离性、读未提交、读提交、可重复读、串行化、一致性、读-写、MVCC、当前读和快照、RR和RC本质区别

文章目录 MySQL3. 事务隔离等级3.1 什么是事务隔离等级3.2 隔离级别3.3 查看与设置隔离性3.4 读未提交【Read Uncommitted】3.5 读提交【Read Committed】3.6 可重复读【Repeatable Read】3.7 串行化【serializable】3.8 一致性【Consistency】 4. 读-写4.1 三个记录隐藏列字段…

python spyne报No module named ‘http.cookies‘的解决

python spyne报No module named ‘http.cookies’ python实现webservice服务端时&#xff0c;会使用spyne这个库&#xff0c;安装后&#xff0c;运行会提示No module named ‘http.cookies’。 尝试过不行的方法 pip install http.cookiespip install http.cookiejar 可行的…

MATLAB中cdf2rdf函数用法

目录 语法 说明 示例 将复数对角矩阵变换为实数块对角矩阵 cdf2rdf函数的功能是将复数对角型转换为实数块对角型。 语法 [Vnew,Dnew] cdf2rdf(V,D) 说明 ​[Vnew,Dnew] cdf2rdf(V,D) 将实矩阵 X 的 [V,D] eig(X) 或 [V,D] eigs(X,___) 的输出从复数对角型转换为实数…

蚁狮优化算法(ALO)与支持向量机(SVM)结合的预测模型及其Python和MATLAB实现

### 一、背景 随着大数据时代的到来&#xff0c;各种复杂数据的处理和分析变得至关重要。在众多数据分析方法中&#xff0c;支持向量机&#xff08;Support Vector Regression, SVR&#xff09;因其优良的回归性能而受到广泛关注。SVR通过构建一个超平面来拟合数据&#xff0c…

【学习笔记】Matlab和python双语言的学习(动态规划)

文章目录 前言一、动态规划动态规划的基本步骤示例1示例2 三、代码实现----Matlab1.示例12.示例2 四、代码实现----python1.示例12.示例2 总结 前言 通过模型算法&#xff0c;熟练对Matlab和python的应用。 学习视频链接&#xff1a; https://www.bilibili.com/video/BV1EK411…

前端工程化工具——plop的使用-生成模板页面

背景 软件列表 软件名称版本号备注vue3.2.13vue-cli5.0.8plop4.0.1 操作步骤 新建vue3工程 vue create test-plop按提示完成操作即可 modules安装工具选择&#xff1a;yarn或npm均可 安装plop模块 yarn add plop -g新建模板文件 page1/index.hbs <template><…