2019-02-20 16:22:29 chenliang0224 阅读数 406
  • C语言项目开发系列视频课程

    项目开发流程: 1)需求分析 2)数据结构分析 3)代码架构分析 4)编写代码 5)测试发布 6)迭代更新 1、小说阅读器 做一个属于自己的阅读器,你想添加的功能分章显示、空格翻页、历史浏览记录…… 2、学员管理系统 通过学员管理系统,可以延伸更多的管理系统哦 3、cJSON 解析器 强化字符串处理, 自定义数据类型的能力. 4、日志库 ……

    860 人正在学习 去看看 杨波

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

JSON源码下载路径

2. 这里直接使用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 运行程序调试信息

标题

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编码以及解码,必须要知道花括号{ }、中括号[ ]、冒号:的含义才可以很方便的进行编解码!

8. 另外以下这位博主写的很详细,详见如下链接

https://www.cnblogs.com/chineseboy/p/3959852.html

2018-01-18 17:29:56 hxm2011 阅读数 1076
  • C语言项目开发系列视频课程

    项目开发流程: 1)需求分析 2)数据结构分析 3)代码架构分析 4)编写代码 5)测试发布 6)迭代更新 1、小说阅读器 做一个属于自己的阅读器,你想添加的功能分章显示、空格翻页、历史浏览记录…… 2、学员管理系统 通过学员管理系统,可以延伸更多的管理系统哦 3、cJSON 解析器 强化字符串处理, 自定义数据类型的能力. 4、日志库 ……

    860 人正在学习 去看看 杨波

最近业务需要跟支付宝进行数据对接,由于对方的数据都是以json格式传送,所以需要对接送格式数据进行解析或组包,cJSON是一种轻量级的数据交换格式。

了解json请参考其官网http://json.org/,cJSON 下载地址http://sourceforge.net/projects/cjson/?source=typ_redirect

文件只有几十k。

test.c 是下载后自带的一个小小的例子,通过这个例子的学习,很快就能掌握json数据结构的构造和解析。

自带例子编译方式如下:

gcc cJSON.c test.c -o jsontest  -lm  

此处记住一定要包含 -lm,因为cJSON.c里面用到了两个数学函数pow floor,否则编译会报错。

一、json库的简单介绍和简单实际应用

cJSON结构体:
typedefstruct cJSON {
structcJSON *next,*prev;
struct cJSON *child;
int type;
char * valuestring;
int valueint;
double valuedouble;
char *string;
}cJSON;


1、cJSON存储的时候是采用链表存储的,其访问方式很像一颗树。每一个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。不过,只有节点是对象或数组才可以有孩子节点。
2、type一共有7种取值,分别是:
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
若是Number类型,则valueint或valuedouble中存储着值,若你期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。
若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。
3、string中存放的是这个节点的名字
二、用法举例
自己根据自带的测试程序编写了一个构造和解析json的例子,代码不是很漂亮,主要是为了介绍一下如何使用json库

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"


int main (int argc, const char * argv[])
{
    cJSON* pRoot = cJSON_CreateObject();
    cJSON* pArray = cJSON_CreateArray();
    cJSON_AddItemToObject(pRoot, "students_info", pArray);
    char* szOut = cJSON_Print(pRoot);


    cJSON* pItem = cJSON_CreateObject();
    cJSON_AddStringToObject(pItem, "name", "chenzhongjing");
    cJSON_AddStringToObject(pItem, "sex", "male");
    cJSON_AddNumberToObject(pItem, "age", 28);
    cJSON_AddItemToArray(pArray, pItem);


    pItem = cJSON_CreateObject();
    cJSON_AddStringToObject(pItem, "name", "fengxuan");
    cJSON_AddStringToObject(pItem, "sex", "male");
    cJSON_AddNumberToObject(pItem, "age", 24);
    cJSON_AddItemToArray(pArray, pItem);


    pItem = cJSON_CreateObject();
    cJSON_AddStringToObject(pItem, "name", "tuhui");
    cJSON_AddStringToObject(pItem, "sex", "male");
    cJSON_AddNumberToObject(pItem, "age", 22);
    cJSON_AddItemToArray(pArray, pItem);


    char* szJSON = cJSON_Print(pRoot);
    printf("%s\n",szJSON);
    cJSON_Delete(pRoot);


    pRoot = cJSON_Parse(szJSON);
    pArray = cJSON_GetObjectItem(pRoot, "students_info");
    if (NULL == pArray) {
        return -1;
    }


    int iCount = cJSON_GetArraySize(pArray);
    int i = 0;
    for (; i < iCount; ++i) {
        cJSON* pItem = cJSON_GetArrayItem(pArray, i);
        if (NULL == pItem){
            continue;
        }
        char *strName = cJSON_GetObjectItem(pItem, "name")->valuestring;
        char *trSex = cJSON_GetObjectItem(pItem, "sex")->valuestring;
        int iAge = cJSON_GetObjectItem(pItem, "age")->valueint;
        printf("---name=%s\n", strName);
        printf("---sex=%s\n", trSex);
        printf("---age=%d\n", iAge);
    }


    cJSON_Delete(pRoot);
    free(szJSON);
    return 0;
}

gcc -o create cJSON.c create.c -lm
./create



2017-05-30 12:59:24 wang93IT 阅读数 6470
  • C语言项目开发系列视频课程

    项目开发流程: 1)需求分析 2)数据结构分析 3)代码架构分析 4)编写代码 5)测试发布 6)迭代更新 1、小说阅读器 做一个属于自己的阅读器,你想添加的功能分章显示、空格翻页、历史浏览记录…… 2、学员管理系统 通过学员管理系统,可以延伸更多的管理系统哦 3、cJSON 解析器 强化字符串处理, 自定义数据类型的能力. 4、日志库 ……

    860 人正在学习 去看看 杨波

今天是端午节,特意写了篇博客,之前工作中遇到用CJson来存储配置文件,对于有的人来说,没用过这种数据格式,更不知道如何使用它,现在我就用我对CJson的理解来记录下CJson的基础使用。


cJSON简介:


JSON(JavaScriptObject Notation)是一种轻量级的数据交换格式。它基于JavaScript的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。了解json请参考其官网http://json.org/,cJSON 下载地址:http://sourceforge.net/projects/cjson/?source=typ_redirect
文件只有几十k,下载完成后解压,cJOSN库,仅有两个文件cJSON.c和cJSON.h。test.c 是下载后自带的一个小小的例子,通过这个例子的学习,很快就能掌握json数据结构的构造和解析。
自带例子编译方式如下:
gcc cJSON.c test.c -o jsontest  -lm  
此处记住一定要包含 -lm,因为cJSON.c里面用到了两个数学函数pow floor,否则编译会报错。

一、json库的简单介绍和简单实际应用
cJSON结构体:

typedef struct cJSON

 {     

  struct cJSON *next,*prev;// 数组 对象数据中用到     
  struct cJSON *child;// 数组 和对象中指向子数组对象或值     
  int type;// 元素的类型,如是对象还是数组     
  char *valuestring;// 如果是字符串     
  int valueint; // 如果是数值     
  double valuedouble;// 如果类型是cJSON_Number     
  char *string;// The item's name string, if this item is the child of, or is in the list of subitems of an object.     
} cJSON;

1、cJSON存储的时候是采用链表存储的,其访问方式很像一颗树。每一个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。不过,只有节点是对象或数组才可以有孩子节点。


2、type一共有7种取值,分别是:
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5

#define cJSON_Object 6


若是Number类型,则valueint或valuedouble中存储着值,若你期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。

若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。


3、string中存放的是这个节点的名字

4、用法:
(1)只需在函数中includecJSON.h头文件,然后和cJSON.c或库文件libcJSON.a一起编译即可使用。

(2)具体函数用法详见cJSON.h中注释


二、使用实例

  1. {     
  2.     "name": "Jack (\"Bee\") Nimble",      
  3.     "format": {     
  4.         "type":       "rect",      
  5.         "width":      1920,      
  6.         "height":     1080,      
  7.         "interlace":  false,      
  8.         "frame rate": 24     
  9.     }     
  10.   
  11. }   

字符串解析成json结构体:
cJSON *root = cJSON_Parse(my_json_string);  

获取某个元素:

  1. cJSON *format = cJSON_GetObjectItem(root,"format");     
  2. int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;  

json结构体转换成字符串:

[html] view plain copy
  1. char *rendered cJSON_Print(root);   

删除:
[html] view plain copy
  1. cJSON_Delete(root);  
构建一个json结构体:
[html] view plain copy
  1. cJSON *root,*fmt; 
  2. char *out;
  3. root cJSON_CreateObject();       
  4. cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));     
  5. cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());     
  6. cJSON_AddStringToObject(fmt,"type",     "rect");     
  7. cJSON_AddNumberToObject(fmt,"width",        1920);     
  8. cJSON_AddNumberToObject(fmt,"height",       1080);     
  9. cJSON_AddFalseToObject (fmt,"interlace");     
  10. cJSON_AddNumberToObject(fmt,"frame rate",   24)  
  11. out =cJSON_Print(root);  
  12. printf("%s\n",out);   
  13. cJSON_Delete(root);  
  14. free(out);  
读取cjson测试:
[html] view plain copy
  1. /***********************************************************************************  
  2. {  
  3.         "message":  "json test",  
  4.         "allRowCount":  2,  
  5.         "root": [{  
  6.                         "value":    "2015-11-16 11:15",  
  7.                         "id":   "2015_20110.10000",  
  8.                         "sex":  "famale"  
  9.                 }],  
  10.         "success":  "true"  
  11. }  
  12. ************************************************************************************/  
  13. #include <stdio.h>  
  14. #include <stdlib.h>  
  15. #include "cJSON.h"  
  16. static int print_jsom(char *json_string)  
  17. {  
  18.     char *out;  
  19.     cJSON *jsonroot = cJSON_Parse(json_string);  
  20.     out=cJSON_Print(jsonroot);  
  21.     printf("%s\n",out);  
  22.   
  23.     cJSON_Delete(jsonroot);  
  24.     free(out);  
  25.     return 1;  
  26. }  
  27. static int print_file(char *filename)  
  28. {  
  29.     FILE *fp;  
  30.     int flen;  
  31.     char *p;  
  32.     if ((fp = fopen (filename, "r")) == NULL)  
  33.     {  
  34.         printf("file open error\n");  
  35.         exit(0);  
  36.     }  
  37.     fseek(fp, 0, SEEK_END);  
  38.     flen = ftell(fp);  
  39.     p = (char *)malloc(flen + 1);  
  40.     fseek (fp, 0, SEEK_SET);  
  41.     fread (p , flen, 1, fp);  
  42.     print_jsom(p);  
  43.     fclose(fp);  
  44.     free(p);  
  45.     return 1;  
  46. }  
  47. int main (int argc, const char * argv[])   
  48. {  
  49.     char *filename="ch.txt";  
  50.     print_file(filename);  
  51.   
  52.     char *my_json_string = "{     \  
  53.             \n\"message\":\"json test\",           \  
  54.             \n\"allRowCount\":2,                   \  
  55.             \n\"root\":[{                          \  
  56.             \n    \"value\":\"2015-11-16 11:15\",  \  
  57.             \n    \"id\":\"2015_20110.10000\",     \  
  58.             \n    \"sex\":\"famale\"               \  
  59.             \n }],                                 \  
  60.             \n\"success\":\"true\"                 \  
  61.             \n}";  
  62.     print_jsom(my_json_string);  
  63.   
  64.     cJSON *jsonroot = cJSON_Parse(my_json_string);  
  65.     printf("success=%s\n",cJSON_GetObjectItem(jsonroot, "message")->valuestring);  
  66.     int taskNum = cJSON_GetObjectItem(jsonroot,"allRowCount")->valueint;  
  67.     printf("allRowCount=%d\n", taskNum);  
  68.     cJSON *taskArry=cJSON_GetObjectItem(jsonroot,"root");//取数组  
  69.     int arrySize=cJSON_GetArraySize(taskArry);//数组大小  
  70.     printf("array size:%d\n",arrySize);  
  71.   
  72.     cJSON *tasklist=taskArry->child;//子对象  
  73.     char *value = NULL;  
  74.     printf("------------------------\n");  
  75.     while(tasklist!=NULL) {  
  76.         value = cJSON_GetObjectItem(tasklist,"value")->valuestring;  
  77.         if (value && strcmp(value, "")) {  
  78.             printf("value=%s\n", value);  
  79.         }  
  80.         value = cJSON_GetObjectItem(tasklist,"id")->valuestring;  
  81.         if (value && strcmp(value, "")) {  
  82.             printf("id=%s\n", value);  
  83.         }  
  84.         value = cJSON_GetObjectItem(tasklist,"sex")->valuestring;  
  85.         if (value && strcmp(value, "")) {  
  86.             printf("sex=%s\n", value);  
  87.         }  
  88.   
  89.         tasklist=tasklist->next;  
  90.     }  
  91.     cJSON_Delete(jsonroot);  
  92.     return 1;  
  93.  }  
编译运行:
[html] view plain copy
  1. gcc -o main cJSON.c main.c -lm  
  2. ./main  

创建cjson并显示:
[html] view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "cJSON.h"  
  4.   
  5. int main (int argc, const char * argv[])  
  6. {  
  7.     cJSON* pRoot = cJSON_CreateObject();  
  8.     cJSON* pArray = cJSON_CreateArray();  
  9.     cJSON_AddItemToObject(pRoot, "students_info", pArray);  
  10.     char* szOut = cJSON_Print(pRoot);  
  11.   
  12.     cJSON* pItem = cJSON_CreateObject();  
  13.     cJSON_AddStringToObject(pItem, "name", "chenzhongjing");  
  14.     cJSON_AddStringToObject(pItem, "sex", "male");  
  15.     cJSON_AddNumberToObject(pItem, "age", 28);  
  16.     cJSON_AddItemToArray(pArray, pItem);  
  17.   
  18.     pItem = cJSON_CreateObject();  
  19.     cJSON_AddStringToObject(pItem, "name", "fengxuan");  
  20.     cJSON_AddStringToObject(pItem, "sex", "male");  
  21.     cJSON_AddNumberToObject(pItem, "age", 24);  
  22.     cJSON_AddItemToArray(pArray, pItem);  
  23.   
  24.     pItem = cJSON_CreateObject();  
  25.     cJSON_AddStringToObject(pItem, "name", "tuhui");  
  26.     cJSON_AddStringToObject(pItem, "sex", "male");  
  27.     cJSON_AddNumberToObject(pItem, "age", 22);  
  28.     cJSON_AddItemToArray(pArray, pItem);  
  29.   
  30.     char* szJSON = cJSON_Print(pRoot);  
  31.     printf("%s\n",szJSON);  
  32.     cJSON_Delete(pRoot);  
  33.   
  34.     pRoot = cJSON_Parse(szJSON);  
  35.     pArray = cJSON_GetObjectItem(pRoot, "students_info");  
  36.     if (NULL == pArray) {  
  37.         return -1;  
  38.     }  
  39.   
  40.     int iCount = cJSON_GetArraySize(pArray);  
  41.     int i = 0;  
  42.     for (; i < iCount; ++i) {  
  43.         cJSON* pItem = cJSON_GetArrayItem(pArray, i);  
  44.         if (NULL == pItem){  
  45.             continue;  
  46.         }  
  47.         char *strName = cJSON_GetObjectItem(pItem, "name")->valuestring;  
  48.         char *trSex = cJSON_GetObjectItem(pItem, "sex")->valuestring;  
  49.         int iAge = cJSON_GetObjectItem(pItem, "age")->valueint;  
  50.         printf("---name=%s\n", strName);  
  51.         printf("---sex=%s\n", trSex);  
  52.         printf("---age=%d\n", iAge);  
  53.     }  
  54.   
  55.     cJSON_Delete(pRoot);  
  56.     free(szJSON);  
  57.     return 0;  
  58. }  
编译运行:
[html] view plain copy
  1. gcc -o create cJSON.c create.c -lm  
  2. ./create  


2019-05-02 19:22:46 oGuiGui12345 阅读数 663
  • C语言项目开发系列视频课程

    项目开发流程: 1)需求分析 2)数据结构分析 3)代码架构分析 4)编写代码 5)测试发布 6)迭代更新 1、小说阅读器 做一个属于自己的阅读器,你想添加的功能分章显示、空格翻页、历史浏览记录…… 2、学员管理系统 通过学员管理系统,可以延伸更多的管理系统哦 3、cJSON 解析器 强化字符串处理, 自定义数据类型的能力. 4、日志库 ……

    860 人正在学习 去看看 杨波

简介

CJson是Lua实现解析json数据的工具类,非常的好用,我们很多时候需要传递一个json数据,然后可以在lua脚本中解析成需要的数据类型,进行使用。

安装

  1. wget http://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz
  2. tar -zxf lua-cjson-2.1.0.tar.gz -C /usr/local/
  3. 然后进入目录 cd /usr/local/lua-cjson-2.1.0
  4. make install
  5. 最后把cjson.so cp 到 /usr/local/lib/lua/5.1/
  6. 创建lua脚本文件03.lua,并写入脚本内容
#!/usr/local/bin/lua
local str1 = '{reoe:{"foo","bar"}}'
local str2 = '[{"name":"asdsd"},{"age":20}]'
local cjson = require "cjson"
local x = cjson.decode(str2)
print(x)

   7.命令行输入lua 0.3.lua,输出结果到控制台成功

[root@localhost bin]# lua 03.lua
table: 0x1370ab0

 

2019-01-23 10:11:27 nanfeibuyi 阅读数 1469
  • C语言项目开发系列视频课程

    项目开发流程: 1)需求分析 2)数据结构分析 3)代码架构分析 4)编写代码 5)测试发布 6)迭代更新 1、小说阅读器 做一个属于自己的阅读器,你想添加的功能分章显示、空格翻页、历史浏览记录…… 2、学员管理系统 通过学员管理系统,可以延伸更多的管理系统哦 3、cJSON 解析器 强化字符串处理, 自定义数据类型的能力. 4、日志库 ……

    860 人正在学习 去看看 杨波

Linux cJSON库的使用、编译为cJSON动态库

一、简述

       记--再linux平台下编译cJSON并简单的使用。

       cJSONFiles.zip:链接: https://pan.baidu.com/s/16JkSONzRy2ZzAvjUXcoD5Q 提取码: 2cvh

       cJSON-master.zip:链接: https://pan.baidu.com/s/17UzsuOh2iDiQgf099R0iYw 提取码: 2nsh 

       编译好的库文件:链接: https://pan.baidu.com/s/1jFhRZ8RDpMftlMKZU5M8_g 提取码: s7ib 

二、源码下载

        官网:https://sourceforge.net/projects/cjson/

        

        gitgub:https://github.com/DaveGamble/cJSON

       

三、使用例子1

      1、从https://sourceforge.net/projects/cjson/下载的源码

          

    2、解压,进入cJSON文件夹,将其中的cJSON.c,cJSON.h,test.c拷贝到Ubuntu下测试

        

   3、编译例子并运行

       

三、使用例子2

      1、从https://github.com/DaveGamble/cJSON下载的源码

                  

     2、解压、将所有文件拷贝到Ubuntu,编译生成库文件

      

测试代码:json.c文件

 

#include <stdio.h>
#include "cJSON.h"

int main(int argc, char* argv[])
{
	char buf[1024] = {" {\"date\":\"20181128\"} "};//要解析的json数据

	cJSON * root = cJSON_Parse(buf);//将字符串格式的json数据转化为JSON对象格式
	if(root == NULL)
	{
		printf("parse error\n");
		return -1;
	}

	cJSON *value = cJSON_GetObjectItem(root, "date");//根据键"date"获取其对应的值
	if(value == NULL)
	{
		printf("getvalue error\n");
		return -1;
	}

	char *data = cJSON_Print(value);//将获取值转化为字符串格式
	if(data == NULL)
	{
		printf("printf error\n");
		return -1;
	}

	printf("data=%s\n", data);//打印获取到的json数据
	
	return 0;
}

附:直接使用.c文件编译

       

linux cJson库使用

阅读数 45

没有更多推荐了,返回首页