【嵌入式开源库:cJSON】 一个轻量级C语言JSON数据解析库用法详解

news2025/2/28 15:31:36

cJSON简介

cJSON是使用C语言编写,用来创建、解析JSON文件的库。cJSON特点就是工程文件简单,只有一个.c一个.h,但提供函数接口功能齐全,麻雀虽小五脏俱全,使得在嵌入式工程中使用起来得心应手。

cJSON获取

https://github.com/DaveGamble/cJSON
只需拉取cJSON.ccJSON.h即可。

在这里插入图片描述

cJSON解析

给出如下JSON格式示例

{
	 "messageType": 2,
	 "messageId": "16493268950279230864908057508987",
	 "imei": "864908057508987898607B1192180035422",
	 "iccid": "898607B1192180035422",
	 "reportTime": "2022-12-16 15:49:00",
 	 "gpsData":
 	 [
 	 		{
 	 			"Longitude":31.23453232,
 	 			"Latitude":118.45345431
			},
			{
				"Longitude":31.23453245,
 	 			"Latitude":118.45345443
			}
			{
				"Longitude":31.23453255,
 	 			"Latitude":118.45345453
			}
   	  ]
}

1、先创建根节点指针

cJSON *root = NULL;
root = cJSON_Parse(msg);

cJSON其实是个结构体类型,被定义如下,cJSON_Parse接口拿到我们的msg数据后会创建一个cJSON结构实例,我们创建的cJSON结构体指针root,会指向这个cJSON结构体实例。既然是实例,就会申请内存。所以最后我们一定不要释放掉这块内存,否则将导致内存泄漏

/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;

cJSON结构体其实是一个抽象的键值对。
他通过成员:前节点、后节点、子节点,来实现JSON结构的嵌套,JSON结构最终在内存中是以一个链表的形式存在。

struct cJSON *next; //前节点
struct cJSON *prev; //后节点
struct cJSON *child;//子节点

而每个节点通过以下成员存储键值

char *valuestring;
int valueint;
double valuedouble;

2、获取键值对

是int类型键值就指向valueint,是字符串类型指向valuestring,字符串数据我们可以用strcpy拷贝出来

cJSON *msgType = NULL;
msgType = cJSON_GetObjectItem(root , "messageType" );
int type = msgType ->valueint

char id[21];
cJSON *iccid = NULL;
iccid = cJSON_GetObjectItem(root , "iccid" );
strcpy(id, iccid ->valuestring);

3、获取数组

如果出现像示例中gpsData这种JSON数组,数组下面又嵌套着新的JSON数据的,我们将使用以下API

cJSON* gpsDataArray = NULL;
cJSON* gpsPoint = NULL;
int gpsArraySize = 0;
double Longitude = 0//经度
double Latitude = 0 //纬度

gpsDataArray = cJSON_GetObjectItem(root, "gpsData");
gpsArraySize = cJSON_GetArraySize(gpsDataArray);
for(i = 0; i < gpsArraySize ; i++)
{
    gpsPoint = cJSON_GetArrayItem(gpsDataArray , i);
    
    Longitude = cJSON_GetObjectItem(gpsPoint , "Longitude");
    Latitude = cJSON_GetObjectItem(gpsPoint , "Latitude");
}

4、释放内存 !

cJSON_Delete(root);

cJSON组装

现在我们试图组装《cJSON解析》中的示例

1、同样,创建根节点

 cJSON* root = NULL;
 root = cJSON_CreateObject();

2、添加键值对成员

cJSON_AddNumberToObject(root , "messageType", 2);

cJSON_AddStringToObject(root , "messageId", "16493268950279230864908057508987");
cJSON_AddStringToObject(root , "imei", 		"864908057508987898607B1192180035422");
cJSON_AddStringToObject(root , "iccid", 	"898607B1192180035422");
cJSON_AddStringToObject(root , "reportTime","2022-12-16 15:49:00");

3、添加数组

和解析相反,我们应该先创建gps点,然后把点添加到数组,再把数组添加到根节点

	//先创建3个gps点
    cJSON* gpsData1 = NULL;
    gpsData2 = cJSON_CreateObject();
    cJSON_AddNumberToObject(gpsData1 ,"Longitude", 31.23453232);
    cJSON_AddNumberToObject(gpsData1 ,"Latitude",  118.45345431;
    cJSON* gpsData2 = NULL;
    gpsData2 = cJSON_CreateObject();
    cJSON_AddNumberToObject(gpsData2 ,"Longitude", 31.23453245);
    cJSON_AddNumberToObject(gpsData2 ,"Latitude",  118.45345443;
    cJSON* gpsData3 = NULL;
    gpsData3 = cJSON_CreateObject();
    cJSON_AddNumberToObject(gpsData3 ,"Longitude", 31.23453255);
    cJSON_AddNumberToObject(gpsData3 ,"Latitude",  118.45345453;

    
	//创建数组,把gps点添加到gps数组
	cJSON* gpsArray = NULL;
    gpsArray = cJSON_CreateArray();
    cJSON_AddItemToArray(gpsArray ,gpsData1 );
    cJSON_AddItemToArray(gpsArray ,gpsData2 );
    cJSON_AddItemToArray(gpsArray ,gpsData3 );

	//把gps数组添加到根节点
	cJSON_AddItemToObject(root,"gpsData",gpsArray );

4、输出组装的JSON

char *msg;
msg =  cJSON_Print(root)

5、依然要记得释放内存

cJSON_Delete(root);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94262.html

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

相关文章

小程序本地 存储/获取值以及删除本地的值

场景&#xff1a;小程序本地存储的方法 wx.setStorageSync&#xff1a;直接给定key和value值 wx.setStorage&#xff1a;需指定key及value&#xff0c;然后再指定相应的值 小程序获取本地值的方法 wx.getStorageSync&#xff1a;直接指定key值获取到对应的数据 wx.getStorage&a…

Node.js模块系统的实现机制简析

目录nodejs模块系统简介C版native模块的定义和加载加载过程JavaScript接口层万能的binding机制JavaScript版native模块的定义和加载js2c技术NativeModule的工作原理Node启动时构造NativeModule对象&#xff0c;完成name到source的映射懒加载机制总结nodejs模块系统简介 Node.j…

[附源码]Nodejs计算机毕业设计基于的校园商城Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Linux系统编程2——进程介绍

文章目录前言一、程序和进程二、并行和并发三、进程控制块PCB进程状态四、创建进程相关函数1、fork函数fork函数总结2、getpid/getppid3、exec函数族3.1、execl函数3.2、execlp函数3.3、exec函数族原理介绍五、进程回收1、为什么要进行进程资源回收2、孤儿进程3、僵尸进程4、进…

传奇GEE引擎版本架设

传奇GEE引擎版本架设 我是艾西今天给大家分享下传奇GEE引擎版本的架设教程 &#xff08;仅做参考&#xff0c;以下内容为显示素材打码部分请读者理解遵守平台GZ&#xff09; 传奇GEE引擎版本我们架设游戏需要用到的工具&#xff1a; 版本&#xff08;游戏类型服务端&#xf…

[附源码]Node.js计算机毕业设计高校学生管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

[附源码]Node.js计算机毕业设计公司疫情健康信息管理系统appExpress

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

冰刃(IceSword)的使用方法(基础篇)

冰刃是一款功能强大的杀毒辅助软件&#xff0c;深受很多杀毒高手的青睐&#xff0c;这里我介绍一下冰刃这个软件的简单使用方法&#xff0c;供大家参考。说句实话&#xff0c;我不是高手&#xff0c;不能像高手一样把一些软件运用自如&#xff0c;所以这个方法可能有很多纰漏或…

怎么去视频的水印?两分钟让你学会操作

从事视频剪辑的小伙伴&#xff0c;想必都需要先从网上查找一些视频片段&#xff0c;再将其整合成一个视频&#xff0c;但是保存下来过后&#xff0c;再打开这些视频时&#xff0c;大家应该都会发现这些视频上都带有水印&#xff0c;很影响视频的观感度&#xff0c;从而可能会降…

Redis宝典

文章目录一.概念1.1 什么是redis1.2 redis优点二.redis的存储结构2.1 结构2.2 渐进式rehash三.Redis数据类型及应用场景3.1 字符串&#xff08;string&#xff09;3.2 字符串列表&#xff08;list&#xff09;3.3 字符串集合&#xff08;set&#xff09;3.4 有序字符串集合&…

找旅馆问题

一 问题描述 有 N 家旅馆&#xff0c;每家旅馆都有位置和价格&#xff0c;有 M 个客人希望找到一家价格可接受的最近旅馆。 二 输入和输出 1 输入 每个测试用例的第 1 行都包含两个整数 N&#xff08;N ≤200000&#xff09;和 M&#xff08;M ≤20000&#xff09;&#xf…

Python之Socket编程: 轻松连接你的应用程序

前言 什么是Socket? Python 的 Socket 模块提供了一个标准的接口&#xff0c;可以让你使用网络连接来通信。 Socket 是一种网络通信技术&#xff0c;它提供了一个通用的接口来连接不同类型的网络&#xff0c;例如互联网、局域网和本地环回地址。你可以使用 Python 的 Socke…

为什么RocketMQ不使用Zookeeper作为注册中心呢?

根据CAP理论&#xff0c;同时最多只能满⾜两个点&#xff0c;而zookeeper满足的是CP&#xff0c;也就是说zookeeper并不能保证服务的可用性&#xff0c;zookeeper在进⾏选举的时候&#xff0c;整个选举的时间太⻓&#xff0c;期间整个集群都处于不可用的状态&#xff0c;而这对…

游戏网页设计成品 学校班级网页制作模板 大学生静态HTML网页源码 dreamweaver网页作业 简单网页课程成品

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

makefile编译一个工程碰到的问题(仅做为记录,没有逻辑)

一、编译选项如下 test : all$(CC) $(CXXFLAGS) -I/DecoderFFMPEGLive/ -o Test/$.o -c Test/test.cpp$(CC) $(CXXFLAGS) -o $ Test/$.o -L. -lDecoderFFMPEGLive -lpthread 报错误&#xff1a;/usr/bin/ld: cannot open output file test: Is a directory 是因为我想生成…

论文笔记CATEGORICAL REPARAMETERIZATION WITH GUMBEL-SOFTMAX

目录Gumbel-Softmax分布Gumbel-Softmax EstimatorStraight-Through (ST) Gumbel-Softmax EstimatorStraight-Through Estimator (STE)Straight-Through (ST) Gumbel-Softmax Estimator参考Gumbel-Softmax分布 Gumbel-Softmax分布是一个定义在单纯形(simplex)上的连续分布。 Gu…

项目成功的制胜法宝——有效的领导力

项目经理在开展项目的过程中&#xff0c;为了确保项目的成功且实现价值交付&#xff0c;往往会使出浑身解数、有勇有谋、甚至熟练使用“孙子兵法”。毕竟在很多情况下&#xff0c;需要“带兵打仗”的项目经理权力微弱&#xff0c;不能像“将军”那般拥有权力的加持、一呼百应。…

javaSE - 认识字符串(String class)上半部分

前言 字符串: 在C语言里面 是 没有字符串类型的&#xff01; 但是&#xff0c;在 Java 和 C 里&#xff0c;有字符串类型【String】 什么是字符串&#xff1f;什么是字符&#xff1f; 在java里面有表示字符串的类 String 使用双引号&#xff0c;且双引号中包含任意数量的字符【…

42 | iptables的使用方法

1 iptables简介 iptables是一个linux下的防火墙工具&#xff0c;能帮助我们基于规则进行网络流量控制。它可以做到&#xff0c;但不限于以下功能&#xff1a; 允许/拒绝某种协议的链接建立&#xff0c;比如TCP&#xff0c;UDP允许/拒绝 来自某个ip的访问允许/拒绝某个端口被访…

田径运动会成绩管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 模块划分&#xff1a;通知类型、通知信息、裁判信息、运动员信息、项目类型、项目信息、场地信息、项目安排、报名信息、…