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

cJSON简介

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

cJSON获取

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

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

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

你可能感兴趣的:(MCU与RTOS,json,c语言,开发语言,嵌入式,cjson)