1. 下载JSON源码,两个文件,分别为cJSON.h、cJSON.c;

​JSON源码下载路径​

2. 这里直接使用JSON源码,不编译成库;

Linux cJSON_json

2.1 cJSON.c 、cJSON.h为第1中下载的源码,这里不贴出;

2.2 test.c源码;

#include "stdlib.h"
#include "stdio.h"
#include "./cJSON.h"

#define FIELD_TYPE_DOUBLE 0 //DOUBLE有符号整形
#define FIELD_TYPE_DOUBLE_U 1 //DOUBLE无符号整形
#define FIELD_TYPE_FLOAT 2 //FLOAT有符号整形
#define FIELD_TYPE_FLOAT_U 3 //FLOAT无符号整形
#define FIELD_TYPE_INT 4 //有符号整形(4字节)
#define FIELD_TYPE_INT_U 5 //无符号整形(4字节)
#define FIELD_TYPE_SHORT 6 //有符号短整形(2字节)
#define FIELD_TYPE_SHORT_U 7 //无符号短整形(2字节)
#define FIELD_TYPE_CHAR 8 //有符号字符(2字节)
#define FIELD_TYPE_CHAR_U 9 //无符号字符(2字节)
#define FIELD_TYPE_STRING 10 //字符串
#define FTILD_TYPE_TIME 11 //时间

//描述:js格式解析,只处理一层的js格式
struct TJS{
char *Field; //客户定义的字段
int FieldType; //字段的格式类型,如整形,字符串
cJSON *pJON; //json解析之后的字符串数据,实际使用时需将字符串转化成对应字段Field的数据
};

//根据客户定义的js字段填充如下结构体
struct TJS g_TJsCfg[] = {
{"startTime", FTILD_TYPE_TIME},
{"endTime", FTILD_TYPE_TIME},
{"UUID", FIELD_TYPE_STRING},
{"subDeviceID", FTILD_TYPE_TIME},
{"UserType", FIELD_TYPE_INT},
{"CredenceType", FIELD_TYPE_INT},
{"credenceNo", FIELD_TYPE_STRING},
{"userName", FIELD_TYPE_STRING},
{"userID", FIELD_TYPE_STRING},
{"opTime", FTILD_TYPE_TIME},
{"placeNo", FIELD_TYPE_STRING},
{"placeLockNo", FIELD_TYPE_STRING},
};

int g_iJsCfgNum = sizeof(g_TJsCfg)/sizeof(g_TJsCfg[0]);

//描述:以下根据具体的需求提取数据,这里只是纯粹的用于验证JSON解析的数据是否正确
void printf_js(cJSON *pJSON, int FieldType)
{
switch(FieldType)
{
case FIELD_TYPE_DOUBLE:
case FIELD_TYPE_DOUBLE_U:
printf("Name: %s, Data:%s\n", pJSON->string, pJSON->valuestring);
break;
case FIELD_TYPE_FLOAT:
break;
case FIELD_TYPE_FLOAT_U:
break;
case FIELD_TYPE_INT:
case FIELD_TYPE_INT_U:
printf("Name: %s, Data:%s\n", pJSON->string, pJSON->valuestring);
break;
case FIELD_TYPE_SHORT:
break;
case FIELD_TYPE_SHORT_U:
break;
case FIELD_TYPE_CHAR:
break;
case FIELD_TYPE_CHAR_U:
break;
case FIELD_TYPE_STRING:
case FTILD_TYPE_TIME:
printf("Name: %s, Data:%s\n", pJSON->string, pJSON->valuestring);
break;
default:
printf("Unsupport fmt:%d\n", FieldType);
}
}

void parse_js(void)
{
//假设接收到客户的js字段数据为
char *pRevJson = "{\"startTime\":\"2017-11-10 08:00:01\",\
\"endTime\":\"2020-11-10 08:00:01\",\
\"UUID\":\"ca23bc4456de223de11a3a7a8ac1d2e3\",\
\"subDeviceID\":\"2020-11-10 08:00:01\",\
\"UserType\":\"1\",\
\"CredenceType\":\"5\",\
\"credenceNo\":\"粤A123456\",\
\"userName\":\"张三\",\
\"userID\":\"1002\",\
\"opTime\":\"2017-11-10 08:00:01\",\
\"placeNo\":\"CA12001\",\
\"placeLockNo\":\"1234566\"\
}";

int idx;


//1. 初始化接收到的客户端json数据
cJSON *root = cJSON_Parse(pRevJson);
if(!root) {
printf("get root faild !\n");
return;
}
//2. 解析客户的数据
for (idx=0; idx<g_iJsCfgNum; idx++)
g_TJsCfg[idx].pJON = cJSON_GetObjectItem(root, g_TJsCfg[idx].Field);

//3. 提取客户的数据
for (idx=0; idx<g_iJsCfgNum; idx++)
{
if (g_TJsCfg[idx].pJON)
printf_js(g_TJsCfg[idx].pJON, g_TJsCfg[idx].FieldType);
else
printf("Name:%s, No data!\n", g_TJsCfg[idx].pJON->string);
}

//4. 释放内存,防止内存泄露!!!
if (root)
cJSON_Delete(root);
}

int main(int argc, char **argv)
{
parse_js();

return 0;
}

2.3 makefile

#根据需求修改如下CC工具链
#CC=nuc972-arm-none-linux-gnueabi-gcc
CC=gcc
EXE=test_json
OBJ=test.c cJSON.c
all:
$(CC) -o $(EXE) $(OBJ) -lm
clean:
rm -rf $(EXE)

3. 执行makefile,编写测试程序,将生成可执行程序"test_json"

chenliang@test:~/smbShare/test/json$ make
gcc -o test_json test.c cJSON.c -lm
chenliang@test:~/smbShare/test/json$ ls
cJSON.c cJSON.h Makefile test.c test_json

4. 运行test_json应用程序

chenliang@test:~/smbShare/test/json$ ./test_json 
Name: startTime, Data:2017-11-10 08:00:01
Name: endTime, Data:2020-11-10 08:00:01
Name: UUID, Data:ca23bc4456de223de11a3a7a8ac1d2e3
Name: subDeviceID, Data:2020-11-10 08:00:01
Name: UserType, Data:1
Name: CredenceType, Data:5
Name: credenceNo, Data:粤A123456
Name: userName, Data:张三
Name: userID, Data:1002
Name: opTime, Data:2017-11-10 08:00:01
Name: placeNo, Data:CA12001
Name: placeLockNo, Data:1234566

5. json数组嵌套解析

5.1 js格式语句

{
"subDeviceID":"12345678901234567890",
"certMode":"2",
"certificateCardList":[{
"UserType":1,
"CredenceType":1,
"credenceNo":"12345678",
"userName":"张三",
"userID":"1234567890",
"blackMode":"3",
"certTimeList":{
"yearList":[{
"start":"2019",
"end":"2019"
}],
"dayTimeList":[{
"start":"08:00:00",
"end":"09:00:00"},
{"start":"12:00:00",
"end":"14:00:00"}
]}
},
{
"UserType":1,
"CredenceType":1,
"credenceNo":"12345679",
"userName":"李四",
"userID":"1234567891",
"blackMode":"3",
"certTimeList":{
"yearList":[{
"start":"2019",
"end":"2019"
}],
"dayTimeList":[{
"start":"08:00:00",
"end":"09:00:00"},
{"start":"12:00:00",
"end":"14:00:00"}
]}
}],
"opTime":"2018-11-27 15:21:00"}

5.2 js数组解析编码

//以下要获取js语句,需强制性加‘/’,实际在接收到对端的js语句可直接解析,不需要加‘/’
char *s = "{\
\"subDeviceID\":\"12345678901234567890\",\
\"certMode\":\"2\",\
\"certificateCardList\":[{\
\"UserType\":1,\
\"CredenceType\":1,\
\"credenceNo\":\"12345678\",\
\"userName\":\"ZhangSan\",\
\"userID\":\"1234567890\",\
\"blackMode\":\"3\",\
\"certTimeList\":{\
\"yearList\":[{\
\"start\":\"2019\",\
\"end\":\"2019\"\
}],\
\"dayTimeList\":[{\
\"start\":\"08:00:00\",\
\"end\":\"09:00:00\"},\
{\"start\":\"12:00:00\",\
\"end\":\"14:00:00\"}\
]}\
},\
{\
\"UserType\":1,\
\"CredenceType\":1,\
\"credenceNo\":\"12345679\",\
\"userName\":\"LiSi\",\
\"userID\":\"1234567891\",\
\"blackMode\":\"3\",\
\"certTimeList\":{\
\"yearList\":[{\
\"start\":\"2019\",\
\"end\":\"2019\"\
\}],\
\"dayTimeList\":[{\
\"start\":\"08:00:00\",\
\"end\":\"09:00:00\"},\
{\"start\":\"12:00:00\",\
\"end\":\"14:00:00\"}\
]}\
}],\
\"opTime\":\"2018-11-27 15:21:00\"}";
//备注:json格式学习--http://www.bejson.com/ 
void test_json()
{
int array_size, certtimelist_arry_size, yearlist_array_size, datetimelist_arry_size, i, k;
cJSON *js_list, *item, *it, *js_name;
cJSON *js_certTimeList, *js_yearlist, *js_datetimelist;
cJSON *js_year_start, *js_year_end;
cJSON *js_time_start, *js_time_end;
char *p;
cJSON *root;

//1. 获取根
root = cJSON_Parse(s);
if(!root) {
printf("get root faild !\n");
return -1;
}
//2. 获取数组列表
js_list = cJSON_GetObjectItem(root, "certificateCardList");
if(!js_list){
printf("no list!\n");
return -1;
}
//3. 获取数组个数
array_size = cJSON_GetArraySize(js_list);
printf("array size is: %d\n",array_size);
//4. 遍历数组
for(i=0; i< array_size; i++) {

printf("-----------------------------\n");
//5. 获取数组成员
item = cJSON_GetArrayItem(js_list, i);
if(!item)
continue;
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
//6. 获取数组成员名字
js_name = cJSON_GetObjectItem(it, "userName");
printf("userName is: %s\n",js_name->valuestring);

//---------------------以下为获取时间------------------------
//1. 获取时间数组列表
js_certTimeList = cJSON_GetObjectItem(item, "certTimeList");
//2. 获取时间数组个数(以下逐次解析,这条语句忽略)
certtimelist_arry_size = cJSON_GetArraySize(js_certTimeList);
//3. 获取数组成员
js_yearlist = cJSON_GetObjectItem(js_certTimeList, "yearList");
if (js_yearlist){
//4. 获取数组成员列表个数
yearlist_array_size = cJSON_GetArraySize(js_yearlist);
for (k=0; k<yearlist_array_size; k++){
//5. 获取数组成员
item = cJSON_GetArrayItem(js_yearlist, k);
if(!item) {
continue;
}
//6. 提取时间年信息
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
//7. 获取数组成员“年”开始
js_year_start = cJSON_GetObjectItem(it, "start");
printf("year start: %s\n",js_year_start->valuestring);
//8. 获取数组成员“年”结束
js_year_end = cJSON_GetObjectItem(it, "end");
printf("year end: %s\n",js_year_end->valuestring);
}
}

//9. 获取数组成员
js_datetimelist = cJSON_GetObjectItem(js_certTimeList, "dayTimeList");
if (js_datetimelist) {
//10. 获取数组成员列表个数
datetimelist_arry_size = cJSON_GetArraySize(js_datetimelist);
for (k=0; k<datetimelist_arry_size; k++){
//11. 获取数组成员
item = cJSON_GetArrayItem(js_datetimelist, k); //4. 获取数组成员
if(!item) {
continue;
}
//12. 提取时间信息
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
//13. 获取数组时间“开始”
js_time_start = cJSON_GetObjectItem(it, "start");
printf("time start: %s\n",js_time_start->valuestring);
//14. 获取数组时间“结束”
js_time_end = cJSON_GetObjectItem(it, "end");
printf("time end: %s\n",js_time_end->valuestring);
}
}
}

if(root)
cJSON_Delete(root);
return 0;
}

int main(int argc, char *argv[])
{
test_json();
return -1;
}

5.3 运行程序调试信息


Linux cJSON_数组_02

标题

6. 按如下格式解析数据

6.1 原始json语句

{
"subDeviceID": "12345678901234567890",
"certMode": "2",
"certificateCardList": [{
"UserType": 1,
"CredenceType": 1,
"credenceNo": "12345678",
"userName": "张三",
"userID": "1234567890",
"blackMode": "3",
"certTimeList": {
"dayTimeList": [{
"start": ["0800", "0900", "1210", "1530"],
"end": ["0800", "0900", "1210", "1530"]
},
{
"start": ["0800", "0900", "1210", "1530"],
"end": ["0800", "0900", "1210", "1530"]
}
]
}
},
{
"UserType": 1,
"CredenceType": 1,
"credenceNo": "12345679",
"userName": "李四",
"userID": "1234567891",
"blackMode": "3",
"certTimeList": {
"dayTimeList": [{
"start": ["0800", "0900", "1210", "1530"],
"end": ["0800", "0900", "1210", "1530"]
},
{
"start": ["0800", "0900", "1210", "1530"],
"end": ["0800", "0900", "1210", "1530"]
}
]
}
}
],
"opTime": "2018-11-27 15:21:00"
}

6.2 转换为C语言能够识别的JSON(只截取6.1中的一部分)

//以下要获取js语句,需强制性加‘/’,实际在接收到对端的js语句可直接解析,不需要加‘/’
char *s = "{\
\"subDeviceID\":\"12345678901234567890\",\
\"certMode\":\"2\",\
\"certificateCardList\":[{\
\"UserType\":1,\
\"CredenceType\":1,\
\"credenceNo\":\"12345678\",\
\"userName\":\"ZhangSan\",\
\"userID\":\"1234567890\",\
\"blackMode\":\"3\",\
\"certTimeList\":{\
\"dayTimeList\": [{\
\"start\": [\"0800\", \"0900\", \"1200\", \"1500\"],\
\"end\": [\"0810\", \"0910\", \"1210\", \"1510\"]\
},\
{\"start\": [\"0820\", \"0920\", \"1220\", \"1520\"],\
\"end\": [\"0830\", \"0930\", \"1230\", \"1530\"]\
}\
]\
}\
}\
],\
\"opTime\":\"2018-11-27 15:21:00\"}";

6.3 源代码

 //备注:json格式学习--http://www.bejson.com/ 
void test_json()
{
int array_size, certtimelist_arry_size, yearlist_array_size, datetimelist_arry_size, time_array_size, i, k, t;
cJSON *js_list, *item, *item_time, *it, *js_name;
cJSON *js_certTimeList, *js_yearlist, *js_datetimelist;
cJSON *js_year_start, *js_year_end;
cJSON *js_time_start, *js_time_end;
char *p;
cJSON *root;

//1. 获取根
root = cJSON_Parse(s);
if(!root) {
printf("get root faild !\n");
return -1;
}
//2. 获取数组列表
js_list = cJSON_GetObjectItem(root, "certificateCardList");
if(!js_list){
printf("no list!\n");
return -1;
}
//3. 获取数组个数
array_size = cJSON_GetArraySize(js_list);
printf("array size is: %d\n",array_size);
//4. 遍历数组
for(i=0; i< array_size; i++) {

printf("-----------------------------\n");
//5. 获取数组成员
item = cJSON_GetArrayItem(js_list, i);
if(!item)
continue;
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
//6. 获取数组成员名字
js_name = cJSON_GetObjectItem(it, "userName");
printf("userName is: %s\n",js_name->valuestring);

//---------------------以下为获取时间------------------------
//1. 获取时间数组列表
js_certTimeList = cJSON_GetObjectItem(item, "certTimeList");
//2. 获取时间数组个数(以下逐次解析,这条语句忽略)
certtimelist_arry_size = cJSON_GetArraySize(js_certTimeList);
//3. 获取数组成员
js_yearlist = cJSON_GetObjectItem(js_certTimeList, "yearList");
if (js_yearlist){
//4. 获取数组成员列表个数
yearlist_array_size = cJSON_GetArraySize(js_yearlist);
for (k=0; k<yearlist_array_size; k++){
//5. 获取数组成员
item = cJSON_GetArrayItem(js_yearlist, k);
if(!item) {
continue;
}
//6. 提取时间年信息
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
//7. 获取数组成员“年”开始
js_year_start = cJSON_GetObjectItem(it, "start");
printf("year start: %s\n",js_year_start->valuestring);
//8. 获取数组成员“年”结束
js_year_end = cJSON_GetObjectItem(it, "end");
printf("year end: %s\n",js_year_end->valuestring);
}
}
//9. 获取数组成员
js_datetimelist = cJSON_GetObjectItem(js_certTimeList, "dayTimeList");
if (js_datetimelist) {
//10. 获取数组成员列表个数
datetimelist_arry_size = cJSON_GetArraySize(js_datetimelist);
for (k=0; k<datetimelist_arry_size; k++){
//11. 获取数组成员
item = cJSON_GetArrayItem(js_datetimelist, k); //4. 获取数组成员
if(!item) {
continue;
}
//12. 提取时间信息
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
#if 0 //原来的解码格式
//13. 获取数组时间“开始”
js_time_start = cJSON_GetObjectItem(it, "start");
printf("time start: %s\n",js_time_start->valuestring);
//14. 获取数组时间“结束”
js_time_end = cJSON_GetObjectItem(it, "end");
printf("time end: %s\n",js_time_end->valuestring);

#else //现在的解码格式
//13. 获取数组时间“开始”
js_time_start = cJSON_GetObjectItem(it, "start");
if (js_time_start){
time_array_size = cJSON_GetArraySize(js_time_start);
printf("------start: time_array_size=%d------\n", time_array_size);
for (t=0; t<time_array_size; t++) {
item = cJSON_GetArrayItem(js_time_start, t);
if(!item)
continue;
printf("t=%d, %s\n", t, item->valuestring);
}
printf("\n");
}
//13. 获取数组时间“结束”
js_time_start = cJSON_GetObjectItem(it, "end");
if (js_time_start){
time_array_size = cJSON_GetArraySize(js_time_start);
printf("------End: time_array_size=%d------\n", time_array_size);
for (t=0; t<time_array_size; t++) {
item = cJSON_GetArrayItem(js_time_start, t);
if(!item)
continue;
printf("t=%d, %s\n", t, item->valuestring);
}
printf("\n");
}

#endif
}
}
}

if(root)
cJSON_Delete(root);
return 0;
}
int main(int argc, char *argv[])
{
test_json();
return -1;
}

6.4 运行结果

chenliang@test:~/smbShare/test/json$ ./test_json 
array size is: 1
-----------------------------
userName is: ZhangSan
------start: time_array_size=4------
t=0, 0800
t=1, 0900
t=2, 1200
t=3, 1500

------End: time_array_size=4------
t=0, 0810
t=1, 0910
t=2, 1210
t=3, 1510

------start: time_array_size=4------
t=0, 0820
t=1, 0920
t=2, 1220
t=3, 1520

------End: time_array_size=4------
t=0, 0830
t=1, 0930
t=2, 1230
t=3, 1530

7. JSON编码

7.1 源码

int jsson_encode(void)
{

cJSON *root;
cJSON *arrayData;
cJSON *dataArray;
cJSON *timeArray;
cJSON *weekArray;
cJSON *weekObj;
cJSON *oneItem;
cJSON *str;
int i;

//以下值从flash中取出按上次的方式转换成16进制字符串
const char *week1Str1[] = {"0800", "0900", "1200", "1500"};
const char *week2Str1[] = {"0810", "0910", "1210", "1510"};
const char *week1Str2[] = {"0820", "0920", "1220", "1520"};
const char *week2Str2[] = {"0830", "0930", "1230", "1530"};

//1. 根创建
root = cJSON_CreateObject();

//2. 增加subDeviceID
str = cJSON_CreateString("12345678901234567890");
cJSON_AddItemToObject(root,"subDeviceID", str);

//3. 增加certMode
cJSON_AddNumberToObject(root,"certMode", 2);

//4. 增加数组Data
arrayData = cJSON_CreateArray();
cJSON_AddItemToObject(root,"Data", arrayData);

//5. 创建Data的数组dataArray
dataArray = cJSON_CreateObject();
cJSON_AddItemToArray(arrayData, dataArray);

//5.1 向Data中增加userType
cJSON_AddNumberToObject(dataArray, "userType", 1);
//5.2 向Data中添加credenceNo
cJSON_AddStringToObject(dataArray, "credenceNo", "12345678");
//5.3 向Data中添加userName
cJSON_AddStringToObject(dataArray, "userName", "ZhangSan");
//5.4 向Data中添加userID
cJSON_AddStringToObject(dataArray, "userID", "1234567890");
//5.5 向Data中添加blackMode
cJSON_AddStringToObject(dataArray, "blackMode", "3");
//5.6 向Data中添加数组timeSegmentList
timeArray = cJSON_CreateArray();
cJSON_AddItemToObject(dataArray,"timeSegmentList", timeArray);

//5.6.1 在数组timeArrayObj 中创建对象 weekObj
weekObj = cJSON_CreateObject();
cJSON_AddItemToArray(timeArray, weekObj);

//5.6.1.1 在对象weekObj 中添加数组 weekArray
weekArray = cJSON_CreateArray();
cJSON_AddItemToObject(weekObj,"week1Segs", weekArray);
//5.6.1.1.1 在weekArrayObj中添加时间段 week1Str1
for (i=0; i<4; i++)
{
oneItem = cJSON_CreateString(week1Str1[i]);
cJSON_AddItemToArray(weekArray, oneItem);
}

//5.6.1.2 在对象weekObj 中添加数组 weekArray
weekArray = cJSON_CreateArray();
cJSON_AddItemToObject(weekObj,"week2Segs", weekArray);
//5.6.1.2.1 在weekArrayObj中添加时间段 week2Str1
for (i=0; i<4; i++)
{
oneItem = cJSON_CreateString(week2Str1[i]);
cJSON_AddItemToArray(weekArray, oneItem);
}

//5.6.2 在timeArrayObj 中新建一个对象 weekObj
weekObj = cJSON_CreateObject();
cJSON_AddItemToArray(timeArray, weekObj);
//5.6.2.1 在对象weekObj 中添加数组 weekArray
weekArray = cJSON_CreateArray();
cJSON_AddItemToObject(weekObj,"week1Segs", weekArray);
//5.6.2.1.1 在weekArrayObj中添加时间段 week1Str2
for (i=0; i<4; i++)
{
oneItem = cJSON_CreateString(week1Str2[i]);
cJSON_AddItemToArray(weekArray, oneItem);
}
//5.6.2.2 在对象weekObj 中添加数组 weekArray
weekArray = cJSON_CreateArray();
cJSON_AddItemToObject(weekObj,"week2Segs", weekArray);
//5.6.2.2.1 在weekArrayObj中添加时间段 week2Str2
for (i=0; i<4; i++)
{
oneItem = cJSON_CreateString(week2Str2[i]);
cJSON_AddItemToArray(weekArray, oneItem);
}

printf("%s\n\n", cJSON_Print(root));
//释放json结构所占用的内存
cJSON_Delete(root);
return 0;
}
int main(int argc, char *argv[])
{
//test_json();
jsson_encode();
return -1;
}

7.2 运行结果

chenliang@test:~/test/json$ ./test_json 
{
"subDeviceID": "12345678901234567890",
"certMode": 2,
"Data": [{
"userType": 1,
"credenceNo": "12345678",
"userName": "ZhangSan",
"userID": "1234567890",
"blackMode": "3",
"timeSegmentList": [{
"week1Segs": ["0800", "0900", "1200", "1500"],
"week2Segs": ["0810", "0910", "1210", "1510"]
}, {
"week1Segs": ["0820", "0920", "1220", "1520"],
"week2Segs": ["0830", "0930", "1230", "1530"]
}]
}]
}

7.3 注意事项

json编码以及解码,必须要知道花括号{ }、中括号[ ]、冒号:的含义才可以很方便的进行编解码!