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

news2024/9/24 5:33:43

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`
  • 四、源码地址

一、cjson下载

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

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

二、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放在源文件中一起编译就可以了。

三、cjson详解

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 解析对象

样例一:

{
	"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 解析数组:方法一(获取列表数量然后按照位置获取)

样例一:

["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遍历)

样例一:

["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 解析对象包含数组

案例:

{
	"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

{
        "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的json
     cJSON *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;
         }
     }
}

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

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;
}

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

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.coloradmin.cn/o/2033816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从专家角度看:2024年值得关注的项目文档工具

国内外主流的10款项目文档管理软件对比&#xff1a;PingCode、Worktile、禅道、Tower、飞书、Smartsheet、Jira、Notion、Wrike、Basecamp。 在项目管理的世界里&#xff0c;选择一个合适的文档管理工具可能就是成功与否的关键。众多的系统和功能看似琳琅满目&#xff0c;但这也…

无字母数字绕过正则表达式

目录 1、题目代码 1.异或 php部分&#xff1a; python代码&#xff1a; 2.或 php代码 python代码 测试结果&#xff1a; 3、取反 php脚本&#xff1a; 测试结果&#xff1a; 1、题目代码 <?php error_reporting(0); highlight_file(__FILE__); $code$_GET[code…

速度曲线轨迹规划程序优化(封装FC)

1、S型速度曲线点动控制功能块 S型速度曲线点动控制功能块(博途SCL代码)-CSDN博客文章浏览阅读16次。点动功能块只有4个约束条件。https://rxxw-control.blog.csdn.net/article/details/139657487 2、梯形速度曲线绝对值定位功能块 梯形速度曲线绝对值定位功能块(博途SCL代码…

设计模式六大原则之:单一职责原则

1. 单一职责简介 设计模式中的单一职责原则&#xff08;‌Single Responsibility Principle, SRP&#xff09;‌是面向对象设计中的一个基本原则&#xff0c;‌它强调一个类应该仅有一个引起它变化的原因。‌换句话说&#xff0c;‌一个类应该负责一组相对独立且紧密相关的职责…

VisionPro二次开发学习笔记13-使用CogToolBlock进行图像交互

该程序演示了如何使用CogToolBlock进行图像交互. 从vpp文件中加载一个ToolBlock。 用户可以通过应用程序窗体上的数字增减控件修改ToolBlock输入端子的值。 用户还可以从coins.idb或采集FIFO中选择图像。 “运行一次”按钮执行以下操作&#xff1a; 获取下一个图像或读取下一…

数学建模学习笔记

数学建模学习笔记 现学现卖&#xff0c;随缘更新QwQ 主要根据b站大师兄的视频整理而成&#xff0c;有不懂的可以去看原视频 List 数学建模学习笔记一、 层次分析法1.1 矩阵的一致性及其检验1.2 权重计算1.3 具体流程 二、模糊综合评测2.1 隶属函数2.2 隶属函数的确定方法2.3 模…

项目管理中的关键节点——里程碑

里程碑作为项目管理过程中的关键节点&#xff0c;它不仅为项目团队提供了清晰的方向和阶段性目标&#xff0c;还确保了项目能够按照既定的路线稳步前进。 里程碑是项目进程中&#xff0c;那些标志着项目阶段完成或关键决策点的重大事件或时间点。与日常任务或活动不同&#x…

图论(强联通分量)

在图论中&#xff0c;特别是在讨论有向图&#xff08;Directed Graph&#xff09;时&#xff0c;我们常常需要了解图的结构特性&#xff0c;比如强联通分量&#xff08;Strongly Connected Components, SCC&#xff09;。了解强联通分量中的各种边对于理解图的整体结构以及某些…

iPhone官方商店软件下载---免费看各种剧第④弹【iOS版包括iPad】

①点击iPhone自带软件App Store ②点击搜索&#xff0c;输入“模数转换器” &#xff0c;点击下载到手机 ③进入软件页面后&#xff0c;我们需要激活页面&#xff0c;点击“setting”&#xff0c;再点击“feedback” ④在反馈界面输入“小饼干”&#xff0c;点击“Summit”&a…

springboot,mysql多数据源-mybaits

为啥要多数据源&#xff0c;因为我现在有个需求&#xff0c;需要将A库的查询结果&#xff0c;写入到B库。 但是原来的springboot里面就只有A库&#xff0c;所以现在要加上B库。 1.修改application.yaml的数据库连接 这个是原来的 现在改成 其实就是将datasource:xxx&#xff…

微型家庭中控STM32+C#上位机_(STM32部分)

今日尝试开发一款简单好学的 C8T6C#_Winform上位机 的微型家庭中控设备的 小试验品&#xff1a; 这个设备将成为我毕设系统的一个小部分...... 主要开发环境与工具介绍&#xff1a; 单片机 STM32F103C8T6 使用标准库函数编程 Visual Studio 2022软件 C# Winform 开发 上位机…

【相机与图像】2. 相机内外参的标定的代码示例

1 摄像头内参的标定 【相机标定具体操作】 使用将要标定的摄像头&#xff0c;以不同的角度采集棋盘格&#xff0c;要保证视野内出现完整的棋盘格。采集图片数量约15张左右即可。 以11*8的棋盘格为例&#xff0c;具体流程如下&#xff1a; step 1. 设置棋盘格3D点&#xff1b;通…

MapReduce_Writable序列化

使用序列化封装对象 将输入的csv按照员工号拆分成每个员工&#xff0c;每个员工存储为员工对象 数据处理过程 employee_noheader.csv 1,ZhangSan,101,5000 2,LiSi,102,6000 3,WangWu,101,5500 4,ZhaoLiu,103,7000 5,SunQi,102,6500pom.xml <?xml version"1.0&qu…

ctfshow-web入门-sql注入(web201-web205)系统练习sqlmap的使用

目录 1、web201 2、web202 3、web203 4、web204 5、web205 开始系统练习sqlmap的使用 1、web201 随便提交一个看下它调用的接口和请求的参数有哪些 可以看到 URL 为&#xff1a; https://32c7d026-d195-4074-a0f9-492c17dc1a2c.challenge.ctf.show/api/?id1&page1&…

微信答题小程序产品研发-前端开发

开发一款答题小程序界面&#xff0c;涉及到的技术栈&#xff0c;主要包括微信小程序的WXML、WXSS、JavaScript等。 由于时间有限&#xff0c;我先大致记录一下各个功能模块的基本开发概要&#xff0c;后面有空了再详细整理&#xff0c;分享给大家。 1. 首页 &#xff08;1&am…

Windows网络重置后无法连接网络

Windows网络重置后重启电脑无法连接到网络 打开命令提示符快捷键winR输入msconfig点击确定 在系统配置中找到服务先全部禁用&#xff0c;在全部启用&#xff0c;点击应用后重启电脑就可以了

LVS的简单配置及对Mysql主从复制的补充

Day 22 LVS的配置 环境准备 DSN() 用来解析各主机的域名和ip地址&#xff0c;配置域名解析huajuan&#xff0c;负责管理其他主机 web1--->web1.tangpin.huajuan web2--->web2.tangpin.huajuan dns--->dns.tangpin.huajuan web1(192.168.2.200) 用nginx…

解决 MacOS 连接公司 VPN 成功但是不能网络的问题

目录 解决办法2024 Mac mini 爆料 解决办法 操作比较简单&#xff0c;修改配置文件即可&#xff08;如果没有则需要手动创建&#xff09;。 sudo vim /etc/ppp/options在此文件下&#xff0c;加入 plugin L2TP.ppp&#xff1a; plugin L2TP.ppp如果文件里有l2tpnoipsec&…

基于ESP32的智能门锁系统测试

项目介绍 基于ESP32的智能门锁系统。可以运用在商务办公、家用住宅、酒店以及公租房短租公寓等领域。基于esp32的智能门锁系统是生物识别技术和嵌入式系统技术的完美结合&#xff0c;基于ESP32系统进行开发&#xff0c;同时在云端服务器搭建了MQTT服务器并连接开源的家庭自动化…

Apple Intelligence 最詳細解說

Apple Intelligence究竟是什麼&#xff1f; 顧名思義&#xff0c;Apple Intelligence就是Apple獨家開發的 AI 模型&#xff08;深度整合至 iOS 18、iPadOS 18 和 macOS Sequoia&#xff09;&#xff0c;旨在透過理解和生成語言和圖像、解讀上下文&#xff0c;並在特定App中執行…