cJSON 使用详解
文章内容转自:https://www.cnblogs.com/catgatp/p/6379955.html 封装成构建以及解析函数的代码网页:
https://www.jb51.cc/json/289736.html https://blog.csdn.net/jenie/article/details/106729511 基础详解: https://blog.csdn.net/xiaolixi199311/article/details/79083356 复杂应用讲解:https://blog.csdn.net/nihaocaofei/article/details/91492555
由于c语言中,没有直接的字典,字符串数组等数据结构,所以要借助结构体定义,处理json。如果有对应的数据结构就方便一些, 如python中用json.loads(json)就把json字符串转变为内建的数据结构处理起来比较方便。
cjson库文件下载: sourceforge地址 一个重要概念: 在cjson中,json对象可以是json,可以是字符串,可以是数字。。。 cjson数据结构定义:复制代码 #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
typedef struct cJSON { struct cJSON *next,prev; / next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ struct cJSON child; / An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. cjson结构的类型上面宏定义的7中之一*/ char *valuestring; /* The item's string, if type==cJSON_String */ int valueint; /* The item's number, if type==cJSON_Number */ double valuedouble; /* The item's number, if type==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; 复制代码
一、解析json
用到的函数,在cJSON.h中都能找到:复制代码 /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ extern cJSON cJSON_Parse(const char value);//从 给定的json字符串中得到cjson对象 / Render a cJSON entity to text for transfer/storage. Free the char when finished. */ extern char cJSON_Print(cJSON item);//从cjson对象中获取有格式的json对象 / Render a cJSON entity to text for transfer/storage without any formatting. Free the char when finished. */ extern char *cJSON_PrintUnformatted(cJSON *item);//从cjson对象中获取无格式的json对象
/* Delete a cJSON entity and all subentities. */ extern void cJSON_Delete(cJSON *c);//删除cjson对象,释放链表占用的内存空间
/* Returns the number of items in an array (or object). */ extern int cJSON_GetArraySize(cJSON array);//获取cjson对象数组成员的个数 / Retrieve item number “item” from array “array”. Returns NULL if unsuccessful. */ extern cJSON *cJSON_GetArrayItem(cJSON array,int item);//根据下标获取cjosn对象数组中的对象 / Get item “string” from object. Case insensitive. */ extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);//根据键获取对应的值(cjson对象)
/* For analysing failed parses. This returns a pointer to the parse error. You’ll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ extern const char *cJSON_GetErrorPtr(void);//获取错误字符串 复制代码 要解析的json
复制代码 { “semantic”: { “slots”: { “name”: “张三” } }, “rc”: 0, “operation”: “CALL”, “service”: “telephone”, “text”: “打电话给张三” } 复制代码 代码:
复制代码 #include <stdio.h> #include <stdlib.h> #include “cJSON.h”
void printJson(cJSON * root)//以递归的方式打印json的最内层键值对 { for(int i=0; i<cJSON_GetArraySize(root); i++) //遍历最外层json键值对 { cJSON * item = cJSON_GetArrayItem(root, i); if(cJSON_Object == item->type) //如果对应键的值仍为cJSON_Object就递归调用printJson printJson(item); else //值不为json对象就直接打印出键和值 { printf("%s->", item->string); printf("%s\n", cJSON_Print(item)); } } }
int main() { char * jsonStr = “{“semantic”:{“slots”:{“name”:“张三”}}, “rc”:0, “operation”:“CALL”, “service”:“telephone”, “text”:“打电话给张三”}”; cJSON * root = NULL; cJSON * item = NULL;//cjson对象
root = cJSON_Parse(jsonStr); if (!root) { printf("Error before: [%s]\n",cJSON_GetErrorPtr()); } else { printf("%s\n", "有格式的方式打印Json:"); printf("%s\n\n", cJSON_Print(root)); printf("%s\n", "无格式方式打印json:"); printf("%s\n\n", cJSON_PrintUnformatted(root)); printf("%s\n", "一步一步的获取name 键值对:"); printf("%s\n", "获取semantic下的cjson对象:"); item = cJSON_GetObjectItem(root, "semantic");// printf("%s\n", cJSON_Print(item)); printf("%s\n", "获取slots下的cjson对象"); item = cJSON_GetObjectItem(item, "slots"); printf("%s\n", cJSON_Print(item)); printf("%s\n", "获取name下的cjson对象"); item = cJSON_GetObjectItem(item, "name"); printf("%s\n", cJSON_Print(item)); printf("%s:", item->string); //看一下cjson对象的结构体中这两个成员的意思 printf("%s\n", item->valuestring); printf("\n%s\n", "打印json所有最内层键值对:"); printJson(root); } return 0;} 复制代码 二、构造json:
构造 json比较简单,添加json对象即可。参照例子一看大概就明白了。 主要就是用,cJSON_AddItemToObject函数添加json节点。复制代码 xtern cJSON *cJSON_CreateObject(void); extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
extern cJSON *cJSON_CreateNull(void); extern cJSON *cJSON_CreateTrue(void); extern cJSON *cJSON_CreateFalse(void); extern cJSON *cJSON_CreateBool(int b); extern cJSON *cJSON_CreateNumber(double num); extern cJSON *cJSON_CreateString(const char *string); extern cJSON *cJSON_CreateArray(void); extern cJSON *cJSON_CreateObject(void); 复制代码 例子: 要构建的json:
复制代码 “semantic”: { “slots”: { “name”: “张三” } }, “rc”: 0, “operation”: “CALL”, “service”: “telephone”, “text”: “打电话给张三” } 复制代码 代码:
复制代码 #include <stdio.h> #include “cJSON.h”
int main() { cJSON * root = cJSON_CreateObject(); cJSON * item = cJSON_CreateObject(); cJSON * next = cJSON_CreateObject();
cJSON_AddItemToObject(root, "rc", cJSON_CreateNumber(0));//根节点下添加 cJSON_AddItemToObject(root, "operation", cJSON_CreateString("CALL")); cJSON_AddItemToObject(root, "service", cJSON_CreateString("telephone")); cJSON_AddItemToObject(root, "text", cJSON_CreateString("打电话给张三")); cJSON_AddItemToObject(root, "semantic", item);//root节点下添加semantic节点 cJSON_AddItemToObject(item, "slots", next);//semantic节点下添加item节点 cJSON_AddItemToObject(next, "name", cJSON_CreateString("张三"));//添加name节点 printf("%s\n", cJSON_Print(root)); return 0;}