由於c語言中,沒有直接的字典,字符串數組等數據結構,所以要借助結構體定義,處理json。如果有對應的數據結構就方便一些, 如python中用json.loads(json)就把json字符串轉變為內建的數據結構處理起來比較方便。
cjson庫文件下載:
一個重要概念:
在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; }