全面详解c语言使用cJSON解析JSON字符[通俗易懂]

全面详解c语言使用cJSON解析JSON字符[通俗易懂]为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件!如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更好!且文件体积大小不到30k,源代码思路也非常清晰,也非常适合研究。点我下载cJSON当我们下载好cJSON只需要把.c和.h文件包含文件拷贝到我们工程目录下,并将头文件和实现文件…

大家好,又见面了,我是你们的朋友全栈君。

 

为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件!

如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更好!

且文件体积大小不到30k,源代码思路也非常清晰,也非常适合研究。

点我下载cJSON

当我们下载好cJSON只需要把.c和.h文件包含文件拷贝到我们工程目录下,并将头文件和实现文件包含进来就可以使用了!

cJSON使用数据结构链表的方式来存储js对象。

 

 

typedef struct cJSON {  //cJSON结构体
       struct cJSON*next,*prev;           /* 遍历数组或对象链的前向或后向链表指针*/
       struct cJSON *child;                   /*数组或对象的孩子节点*/
       int type;                                     /* key的类型*/
       char *valuestring;                       /*字符串值*/
       int valueint;                                /* 整数值*/
       double valuedouble;                    /* 浮点数值*/
       char *string;                               /* key的名字*/
} cJSON;

 

 

正所谓万丈高楼平地起,先从最简单的开始!

 

 

先来介绍四个常用的cJSON函数:

 

cJSON *cJSON_Parse(const char *value);

 

作用:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体

返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL

 

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

作用:获取JSON字符串字段值

返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL

 

 

char  *cJSON_Print(cJSON *item);

作用:将cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串

 

返回值:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL

 

 

void   cJSON_Delete(cJSON *c);

作用:释放位于堆中cJSON结构体内存

 

返回值:无

 

假如说有这样的一个JSON字符串

 

{
 "test_1":"0"
 "test_2":"1"
 "test_3":"2"
} //json_string //json_string

这是最简单的JSON字符串

我们首先要先将这个字符串打包成cJSON数据格式

 

cJSON* cjson = cJSON_Parse(json_string);

打包后使用if语句或三目表达式判断一下是否将JSON字符串打包成cJSON数据格式

if(cjson == NULL){
printf("json pack into cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}

 

然后依次获取json字符串中的每个字段的值并打印输出
//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
char* test_1_string = cJSON_GetObjectItem(cjson,"test_1")->valuestring;
char* test_2_string = cJSON_GetObjectItem(cjson,"test_2")->valuestring;
char* test_3_string = cJSON_GetObjectItem(cjson,"test_3")->valuestring;
//打印输出
printf("%s",*test_1_string);
printf("%s",*test_2_string);
printf("%s",*test_3_string);

最后别忘记释放内存

 

 

//delete cjson
cJSON_Delete(cjson);
cJSON_Delete(test_arr);
cJSON_Delete(arr_item);

 

完整代码:

 

#include <stdio.h>
#include <cJSON.h>
int main(){
char* json_string =\ 
//用char* 模拟一个JSON字符串
"{"\
 "test_1":"0"\
 "test_2":"1"\
 "test_3":"2"\
"}";
//JSON字符串到cJSON格式
cJSON* cjson = cJSON_Parse(json_string); 
//判断cJSON_Parse函数返回值确定是否打包成功
if(cjson == NULL){
printf("json pack into cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}

//获取字段值
//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
char* test_1_string = cJSON_GetObjectltem(cjson,"test_1")->valuestring;
char* test_2_string = cJSON_GetObjectltem(cjson,"test_2")->valuestring;
char* test_3_string = cJSON_GetObjectltem(cjson,"test_3")->valuestring;

//打印输出
printf("%s",*test_1_string);
printf("%s",*test_2_string);
printf("%s",*test_3_string);

//delete cjson
cJSON_Delete(cjson);

}

是不是很easy?下面来教大家如何使用cJSON解析数组!

{
 "test_1":"1",
 "test_2":"2",
 "test_arr":[{
{
  "test_1":"arr_1",
  "test_2":"arr_2",
  "test_3":"arr_3"
},
{
 "test_1":"1",
 "test_2":"2",
 "test_3":"3"
}
}],
"test_3" :"3"
}//json_arr string

在开始前介绍一个函数

int	  cJSON_GetArraySize(cJSON *array);

作用:获取数组成员对象个数
返回值:数组成员对象个数

 

首先第一步打包

 

cJSON* cjson = cJSON_Parse(json_arr_string);

第二步判断打包是否成功

 

 

if(cjson == NULL){
printf("cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}

第三步获取数组对象

cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr");

第四步获取数组对象个数便于循环

int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2

第五步获取test_arr数组对象孩子节点

cJSON* arr_item = test_arr->child;//子对象

第六步循环获取数组下每个字段的值并使用cJSON_Print打印:

for(int i = 0;i <=(arr_size-1)/*0*/;++i){
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3"));
arr_item = arr_item->next;//下一个子对象
}

最后别忘记释放

 

 

cJSON_Delete(cjson);

完整代码:

 

 

#include <stdio.h>
#include <cJSON.h>
int main(){
char* json_string =\ 
//用char* 模拟一个JSON字符串
“{”,\
 "test_1":"1",\
 "test_2":"2",\
 "test_arr":"[{",\
"{",\
  "test_1":"arr_1",\
  "test_2":"arr_2",\
  "test_3":"arr_3",\
"}",\
"{"\
 "test_1":"1",\
 "test_2":"2",\
 "test_3":"3",\
"}",\
"}]",\
"test_3" :"3",\
"}"//json_arr string;

//第一步打包JSON字符串
cJSON* cjson = cJSON_Parse(json_arr_string);

//判断是否打包成功
if(cjson == NULL){
printf("cjson error…")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}

//获取数组对象
cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr");

//获取数组对象个数便于循环
int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2

//获取test_arr数组对象孩子节点
cJSON* arr_item = test_arr->child;//子对象

//循环获取数组下每个字段的值并使用cJSON_Print打印
for(int i = 0;i <=(arr_size-1)/*0*/;++i){
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3"));
arr_item = arr_item->next;//下一个子对象
}

//delete cjson 这里只需要释放cjson即可,因为其它的都指向它
cJSON_Delete(cjson);

 

 

如果觉得博主写的不错,可以加技术交流群吖:815060222

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147516.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 进程调度程序设计实验报告_进程调度模拟程序设计实验报告

    进程调度程序设计实验报告_进程调度模拟程序设计实验报告进程调度的设计与实现中文摘要无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。关键词进程调度C++优先级生命周期pidstatus前言实验目的1、综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布…

    2022年9月29日
    2
  • 事务的四种隔离级别_事务默认的隔离级别

    事务的四种隔离级别_事务默认的隔离级别数据库事务的隔离级别有4种,由低到高分别为Readuncommitted、Readcommitted、Repeatableread、Serializable。Readuncommitted读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,

    2022年10月14日
    2
  • 运维人员常用到的 11 款服务器监控工具

    运维人员常用到的 11 款服务器监控工具点击上方“民工哥技术之路”,选择“设为星标”回复“1024”获取独家整理的学习资料!服务器监控工具功能相当强大,无论何时何地,我们都可以了解到服务器的功能以及性能。服务器监控工具的使用,…

    2022年5月20日
    44
  • FreeWebHostingArea老牌1.5G无限流量免费PHP空间申请使用「建议收藏」

    FreeWebHostingArea老牌1.5G无限流量免费PHP空间申请使用「建议收藏」FreeWebHostingArea是美国的一个老牌的免费空间服务商,从2005年开始提供免费PHP空间服务。我在2009年的时候就推荐过它(这篇文章),到现在这个空间依然还存活着。和同类的老牌的免费空间超多的空间和流量限制等特点所不同,FreeWebHostingArea的免费PHP空间大小1.5GB,月流量为无限流量,并且可以绑定自己的顶级域名。FreeWebHostingArea之所…

    2022年10月8日
    2
  • 在官网下载最新版Java

    在官网下载最新版Java在Oracle官网下载最新版Java1.进入oracle官网https://www.oracle.com2.点击下拉菜单中的java3.点击如图所示4.点击最新版的javase5.若要下载其他版本,则拉滚动条至最下方,点击如图所示6.各个版本的JavaSE都展示出来了,如图所示,这里下载JavaSE9为例7.勾选下方的AcceptLicenseAgreement,否…

    2022年7月7日
    41
  • 字符串的匹配算法_多字符串匹配

    字符串的匹配算法_多字符串匹配目录需求基础知识逻辑解析源码实现需求先简单描述溪源曾经遇到的需求:需求一:项目结果文件中实验结论可能会存在未知类型、转换错误、空指针、超过索引长度等等。这里是类比需求,用日常开发中常出现的错误类型作为需求,如果要以上结论则判断这个项目检测失败;解决方案一:大家常用的方式可能是if(){continue;}esleif(){continue;}…或者switch-case等;方案二:可能会使用集合contain()方法;方案三:依次匹配字符串中字符(暴力匹配);以上两种方案都能解决;然

    2022年8月21日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号