初识cJSON

article/2025/8/26 17:58:31

先把 cJSON的结构体定义po上来:
cJSON结构体
先讲怎么用,再讲每一步操作的作用,最后有可能的话再讲原理。

直接先po个简单示例,看看我们如何通过cJSON来解析一个JSON数据。
cJSON解析实例
先试着能不能看懂(估计是看不懂了),算了算了,直接看看不懂,先来讲点“前言”。
.
.
.
.
我们先来讲讲几个用到的函数。
首先是 **cJSON cJSON_Parse(const char value);
可以看见,函数的返回类型是一个cJSON指针。函数的传入参数是一个字符指针。该函数的作用是将json格式的字符串转换成json对象。具体为:将一个JSON数据包(即传入的字符指针所指向地址存放的数据),按照cJSON结构体的结构把整个数据包序列化,并在堆中开辟一块内存来存储cJSON结构体(这个作用解释得跟没解释差不多hhh,先简单理解成初始化一段JSON数据包),而如果传入该函数的(也就是该char指针所指向的字符串)不是一段JSON格式的数据,则函数返回NULL指针。如果传入的是JSON数据包,且“初始化”成功,则函数返回一个指向内存块中的cJSON的指针(也就是返回一个cJSON指针,该指针指向该JSON数据包)。
举个例子:

char example[] ={\“name\”:\”How\”,\”age\”:18};	//一个存储json数据包的字符串
cJSON * json;	//创建一个名为json的cJSON指针
json = cJSON_Parse(example);	//判断example是否为JSON数据包
//如果是,则序列化example,然后返回一个cJSON指针
//将返回的指针赋给json变量,即,json指针变量现在指向example这个JSON数据包

.

再来看看 **cJSON *cJSON_GetObjectItem(cJSON object,const char string);
同样的,函数的返回类型是一个cJSON指针。函数的传入参数是一个cJSON指针,和一个字符指针。该函数的作用是,获取JSON数据包中某字符串所对应的字段值,并返回一个指向JSON的cJSON指针。这么说可能不好理解,我们还是来举个例子:

char example[] ={\“name\”:\”How\”,\”age\”:18};
cJSON * json;
cJSON * json_age;//这里我们新建一个名为json_age的cJSON指针
json = cJSON_Parse(example);
json_age = cJSON_GetObjectItem(json, "age");//这句代码的作用是:
//向函数提供一个指向JSON数据包的cJSON指针,即json
//以及提供一个该JSON数据包中的某个key的变量名
//那么函数就会返回一个指向该key变量的值value的cJSON指针
//将返回的指针赋给json_age,于是json_age现在指向age的值
//这样的话,我们就可以通过json_age来访问并打印该值了,如:
if( json_age -> type == cJSON_Number )	//判断age的值是否为数字
{printf("age: %d\n", json_age->valueint);	//若是,以访问成员变量的方式打印
}

(这个时候再回头看看cJSON结构体的定义,里面就有type和valueint,即是cJSON的属性之一)
.
.
再来看看 **char cJSON_Print(cJSON item);
返回类型是一个字符指针。传入参数是一个cJSON指针。该函数的作用是,从传入指针所指的cJSON数据中提取JSON对象的数据,并在堆中开辟一块char*的内存空间存储JSON字符串。即从cJSON对象中获取有格式的JSON对象。(cJSON结构体中不但包含JSON结构的数据——key和value,还包含了其它一些属性作为成员变量——如type,valueint)所以通过cJSON_Print函数就能把cJSON中的JSON数据提取出来,并返回给一个字符指针。
还是来举个例子:

char example[] ={\“name\”:\”How\”,\”age\”:18};
cJSON * json;
char * output;
json = cJSON_Parse(example);
output = cJSON_Print(json);
printf("%s\r\n",output);

这样就把example解析成JSON字符串并输出了。但是有人就会问了,这不是瞎折腾吗?example不是本来就是JSON数据格式的吗?(%@¥&@%63¥emmm我也不知道…)
.
.
再来看看 *void cJSON_Delete(cJSON c);
这个很好理解,其作用就是释放cJSON指针占用的内存。
举例比如cJSON_Delete(json); cJSON_Delete(json_age);
.
.
.
.
好了,有了以上的了解,我们再回过头来看文章一开头的代码:

#include <stdio.h>
#include <stdlib.h>
#include "cjson/cJSON.h"//新建一个名为text的json格式的字符串
char text[] = "{\"timestamp\":\"2019-03-03 08:45:57\", \"value\":1}";void main(int argc, const char *argv[])
{cJSON *json, *json_value, *json_timestamp;	//三个cJSON指针变量json = cJSON_Parse(text);	//将text字符串转换成cJSON对象if(NULL == json)	//如果text不是json格式{printf("Error before: [%s]\n", cJSON_GetErrorPtr());return -1;}//用json_value指针指向json变量所指的cJSON对象中value的值json_value = cJSON_GetObjectItem(json, "value");if(json_value->type == cJSON_Number)		//如果该值符合我们所想{printf("value: %d\n", json_value->valueint);}//同理json_timestamp = cJSON_GetObjectItem(json, "timestamp");if(json_timestamp->type == cJSON_String){printf("%s\n", json_timestamp->valuestring);}//释放json这个cJSON变量所占用的内存cJSON_Delete(json);
}

以上,我们就实现了JSON字符串的解析,其目的就是使之成为一个对象,让我们能够去访问该字符串里面的各种数据。

那么,前面我们是通过已有JSON字符串来解析成对象,那么我们能不能反过来,自己创建一个JSON对象呢?答案当然是可以的。能力有限,不解释,直接po代码了:

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"void main(void)
{cJSON * student_json;	//学生信息cJSON * grades_json;	//成绩信息char * output = NULL;	//用于输出json字符串/student_json = cJSON_CreateObject();grades_json = cJSON_CreateObject();cJSON_AddItemToObject(student_json, "name", cJSON_CreateString("陈how"));cJSON_AddItemToObject(student_json, "qq", cJSON_CreateNumber(772541523));cJSON_AddItemToObject(student_json, "sex", cJSON_CreateString("男"));cJSON_AddItemToObject(student_json, "status", cJSON_CreateString("damn-single"));cJSON_AddItemToObject(student_json, "成绩", grades_json);cJSON_AddItemToObject(grades_json, "专业课", cJSON_CreateString("awful"));cJSON_AddItemToObject(grades_json, "学科竞赛", cJSON_CreateString("not bad"));cJSON_AddItemToObject(grades_json, "文化素养", cJSON_CreateString("so-so"));cJSON_AddItemToObject(student_json, "备注", cJSON_CreateString("这是一条备注"));output = cJSON_Print(student_json);if( output == NULL )	printf("error!\r\n");else	printf("Info:\r\n %s \r\n", output);/cJSON_Delete(student_json);cJSON_Delete(grades_json);free(output);/}

其输出结果为:
输出结果

P.S. 上面这段代码一开始我在STM32里面敲,然后用串口调试助手打印信息,结果不行,cJSON_Print(student_json)返回的是NULL,原因大概是因为由于是在STM32里面,然后类似于内存分配啥的问题,内存不够之类(因为代码我单条单条在STM32都能实现,但是一次性要打印这么多数据就崩了)

以上。

参考资料:
全面详解c语言使用cJSON解析JSON字符
JSON的简单介绍&cJSON库使用(一)
cJSON详解
JSON介绍
cJSON的使用方法
STM32 keil环境下移植cJSON
STM32移植cJSON[注意用free()释放内存]
CSDN:去掉博客中的图片水印 /狗头


http://chatgpt.dhexx.cn/article/Ea8jlirT.shtml

相关文章

cJSON学习

最近在做数据上三大云平台的项目&#xff0c;用的是MQTT协议&#xff0c;阿里云、腾讯云、华为云那边解析数据用的是json格式&#xff0c;下发的也是json格式&#xff0c;所以特地学一下json的封装和解析过程&#xff0c;以及其API的使用&#xff0c;作了以下笔记。 文章目录 …

25cJSON

JSON介绍 JSON(JavaScript Object Notation,JS对象表示法) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。…

【万字详解】cJSON解析

目录 1、通过README文件&#xff0c;初步了解cJSON&#xff1a; 1.1、头文件的开头和结尾&#xff1a; 1.2、头文件关于cJSON类型的宏定义 1.3、头文件中的extern 2、阅读并且分析cJSON源码 2.1、结构体struct cJSON&#xff08;算法设计思想&#xff09;&#xff1a; 2…

cJSON库用法详解

cJSON库用法详解 问题和需要注意的地方一、JSON、cJSON简介1. JSON 简介2. JSON 语法3. 开源库cJSON简介 二、使用cJSON构造JSON1. cJSON库函数介绍2. 使用cJSON构造JSON 三、使用cJSON解析JSON 由于c语言中&#xff0c;没有直接的字典&#xff0c;字符串数组等数据结构&#x…

cJSON使用详细教程 | 一个轻量级C语言JSON解析器

1. JSON与cJSON JSON —— 轻量级的数据格式 JSON 全称 JavaScript Object Notation&#xff0c;即 JS对象简谱&#xff0c;是一种轻量级的数据格式。 它采用完全独立于编程语言的文本格式来存储和表示数据&#xff0c;语法简洁、层次结构清晰&#xff0c;易于人阅读和编写&…

OSPF报文与LSA

1. OSPF报文 OSPF报文 Hello 报文、 DD 报文、 LSR 报文、 LSU报文、LSAck 报文 OSPF 头部 OSPF 用 IP来封装协议报文&#xff0c;协议号89&#xff0c;5种OSPF的报文具有相同OSPF 头部。 OSPF 头部中关注的字段主要有&#xff1a; version&#xff1a; IPv4 OSPFv2 值为2&…

OSPF中的LSA

LSA LSA的基本信息 LSA --- 链路状态通告 --- ospf协议在不同网络环境下产生的鞋带不同信息的载体 LSDB --- 链路状态数据库 SPF --- 最短路径优先算法 Type --- LSA的类型&#xff0c;在OSPFV2版本中&#xff0c;需要掌握的LSA类型一共有六中。 LinkState ID --- 链路状态…

OSPF中LSA相关内容

OSPF的LSA LSA — 链路状态通告 — OSPF协议在不同的网络环境下携带和传递的信息 LSDB — 链路状态数据库 SPF ---- 最短路径优先算法 [Huawei]dis ospf lsdb — 查看lsa信息 LSA头部&#xff08;之后的每条lsa信息都要携带此头部&#xff09; LSA头部内容&#xff1a; 1…

OSPF的Router-LSA和Network-LSA

文章目录 Router-LSARouter-LSA描述P2P网络Router-LSA描述MA网络或NBMA网络 Network-LSANetwork-LSA描述MA网络或NBMA网络 OSPF区域内LSDBSPF计算过程SPF算法构建SPF树计算最优路由查看OSPF路由表 单区域OSPF配置实现查看OSPF邻居状态 Router-LSA Router-LSA描述P2P网络 <R…

OSPF 之 6类LSA详解

目录 1类LSA&#xff1a;router -LSA 2类LSA &#xff0c;network LSA &#xff0c;网络LSA 3类LSA &#xff1a;summary LSA 汇总LSA 5类LSA&#xff1a; 外部LSA 4类LSA&#xff1a; summary ASBR LSA 7类LSA &#xff1a; NSSA LSA 1类LSA&#xff1a;router -LSA …

六类LSA及其作用

LSA&#xff08;链路状态通告&#xff09; LSA的组成 TYPE&#xff1a;LSA的类型&#xff0c;在OSPFV2中&#xff0c;需要掌握的有六种 LINK-State ID&#xff1a;链路状态标识符&#xff0c;用来标记一条LSA信息&#xff0c;相当于是一条LSA的名字 AdvRouter&#xff1a;通告…

图解 OSPF :什么是 LSA ?

大家好&#xff0c;我是小弗。我们都知道了&#xff0c;运行链路状态路由协议的路由器是交换链路状态信息。所有路由器都会生成自己直连接口状态的链路信息&#xff0c;并通告出去。路由器把在网络中收到的链路状态信息存入 LSDB&#xff08;链路状态数据库&#xff09;&#x…

ospf几种lsa

ospf网络类型 1.点到点 点到点网段 2.广播网络 transit网段&#xff08;至少有两台路由器的广播型网段&#xff09; 3.NBMA transit网段 4.点到多点 ospf网段的类型(网段的类型只与网络的类型有关) 1.transit网段 2.stub网段 3.点到点网段 4.virtual 一类的lsa rout…

OSPF的6种LSA

目录 一、6种LSA的简单介绍 1.1 1类LSA 1.1.1 1类LSA基础 1.1.2 1类LSA的报文格式&#xff1a; 1.1.3 1类LSA的链路类型&#xff08;link type&#xff09; 1.2 2类LSA 1.2.1 2类LSA基础 1.2.2 2类LSA的报文格式 1.3 3类LSA 1.3.1 3类LSA基础 1.3.2 3类LSA的报文…

LSA潜在语义分析

【转自&#xff1a;https://blog.csdn.net/roger__wong/article/details/41175967】 原文地址&#xff1a;http://en.wikipedia.org/wiki/Latent_semantic_analysis 前言 浅层语义分析&#xff08;LSA&#xff09;是一种自然语言处理中用到的方法&#xff0c;其通过“矢量语…

OSPF的LSA

文章目录 ospf的lsaLSA的头部信息一类LSA:Router二类LSA:Network三类LSA:Sum-net五类LSA&#xff1a;External四类LSA&#xff1a;Sum-Asbr ospf的lsa ospf本质是通过lsa(链路状态通告)洪泛&#xff0c;将运行ospf域内的所有lsa存放到本地lsdb(链路状态数据库)&#xff0c;然后…

LSA类型详解

在OSPF中有6种常用的LSA类型&#xff0c;分别为&#xff1a; Router-LSA&#xff08;1类&#xff09;、 Network- LSA&#xff08;2类&#xff09;、 Summary- LSA&#xff08;3类&#xff09;、 ASBR-Summary- LSA&#xff08;4类&#xff09;、 AS-External- LSA&#xff08;…

OSPF 之 LSA限制

目录 特殊区域 1.stub 区域&#xff0c; 末节区域 2.完全的末节区域 3.NSSA区域&#xff1a;&#xff08;not so stub area&#xff09; 非完全末节区域 4.完全的非完全的末节区域 LSA汇总 1. 3类LSA汇总&#xff1a; 2. 5类LSA 汇总&#xff1a; 3. 7类LSA 汇总&…

LSA类型

类型 LSID 通告者AdvRouter 作用范围 携带信息 Type-1LSA Router 通告者RID 区域内所有运行ospf协议的路由器的RID 单区域内部 拓扑信息&#xff0c;本地接口直连拓扑 Type-2LSA network DR接口的ip地址 DR锁在的路由器的RID 单区域内部 单个MA网络拓扑信息的补充…

OSPF协议总结5(六种LSA)

LSA----链路状态通告--- OSPF协议在不同网络环境下产生的携带不同信息的载体。 LSDB --链路状态数据库 SPF ---最短路径优先算法 查看LSDB数据库&#xff1a; Type --- LSA的类型&#xff0c;在OSPFV2版本中&#xff0c;需要掌握的L SA类型一共有6种。LinkState ID ---链路状态…