對於c語言來說是沒有字典這樣的結構的,所以對於解析json格式的數據來說不是那么好解析,但是有些時候又會需要處理這樣的數據格式,這里就有一個解析json的函數庫可以給我們使用了。這個函數庫就是cJSON了。這里提供了下載資源可以下載后直接用。
https://files.cnblogs.com/files/piaoyang/cJSONFiles.rar
自己使用時可以只需要其中的cJSON.c和cJSON.h文件就可以了,只需要將cJSON和自己的main文件一起編譯即可。
主要函數接口介紹:
這里有個很重要的結構體是需要用到的就是cJSON 結構體如下:
typedef struct cJSON {
struct cJSON *next,*prev; /* 遍歷數組或對象鏈的前向或后向鏈表指針*/
struct cJSON *child; /*數組或對象的孩子節點*/
int type; /* key的類型*/
char *valuestring; /*字符串值*/
int valueint; /* 整數值*/
double valuedouble; /* 浮點數值*/
char *string; /* key的名字*/
} cJSON;
說明:
1、cJSON是使用鏈表來存儲數據的,其訪問方式很像一顆樹。每一個節點可以有兄弟節點,通過next/prev指針來查找,它類似雙向鏈表;每個節點也可以有孩子節點,通過child指針來訪問,進入下一層。只有節點是對象或數組時才可以有孩子節點。
2、type是鍵(key)的類型,一共有7種取值,分別是:False,Ture,NULL,Number,String,Array,Object。
若是Number類型,則valueint或valuedouble中存儲着值。若期望的是int,則訪問valueint,若期望的是double,則訪問valuedouble,可以得到值。
若是String類型的,則valuestring中存儲着值,可以訪問valuestring得到值。
3、string中存放的是這個節點的名字,可理解為key的名稱。
重要的接口函數:
1.cJSON *cJSON_Parse(const char *value);
解析JSON數據包,並按照cJSON結構體的結構序列化整個數據包。可以看做是獲取一個句柄。
2.cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
功能:獲取json指定的對象成員
參數:*objec:第一個函數中獲取的句柄。
string:需要獲取的對象
返回值:這個對象成員的句柄 如果json格式的對象成員直接就是字符串那么就可以直接通過結構體中的valuestring元素來獲取這個成員的值
3.cJSON *cJSON_GetArrayItem(cJSON *array,int item);
功能:有可能第二個函數中獲取到的是成員對象值是一個數組,那么就需要用到這個函數。用來獲取這個數組指定的下標對象
參數:*array:傳入第二步中返回的值
item:想要獲取這個數組的下標元素
返回值:這個數組中指定下標的對象。然后在對這個返回值重復使用第二步函數就可以獲取到各個成員的值了。
也就是說對象是數組的比是字符串的要多用一個cJSON_GetArrayItem函數,其他的沒區別。
4.cJSON_Delete()
用來釋放你第一步獲取的句柄,來釋放整個內存。用在解析完后調用
介紹完了下面就看實例
用於解析的json結構,這里我使用配置文件保存的json結構,然后解析這個配置文件。用於測試json結構如下:
{"syslog_db":[{"db_user":"xxx","db_password":"yyy","db_type":"ORACLE","db_ip":"172.16.1.248","db_port":"1521","db_name":"orcl","sql":"select * from syslog"}],
"syslog_source":[{"send_ip":"172.0.0.8","send_port":"8","send_protocal":"TCP"}],
"syslog_enable":"1"
}
三個大的對象分別有兩個是數組一個是直接可以獲取的。代碼如下:
1 #include <stdio.h> 2 #include "cJSON.h" 3 4 int main() { 5 FILE *fp = NULL; 6 cJSON *json; 7 char *out; 8 char line[1024] = {0}; 9 10 if(NULL != (fp = fopen("./test.ply", "r"))) { 11 while (NULL != fgets(line, sizeof(line), fp)) { 12 json=cJSON_Parse(line); //獲取整個大的句柄 13 out=cJSON_Print(json); //這個是可以輸出的。為獲取的整個json的值 14 cJSON *arrayItem = cJSON_GetObjectItem(json,"syslog_db"); //獲取這個對象成員 15 cJSON *object = cJSON_GetArrayItem(arrayItem,0); //因為這個對象是個數組獲取,且只有一個元素所以寫下標為0獲取 16 17 /*下面就是可以重復使用cJSON_GetObjectItem來獲取每個成員的值了*/ 18 cJSON *item = cJSON_GetObjectItem(object,"db_user"); // 19 printf("db_user:%s\n",item->valuestring); 20 21 item = cJSON_GetObjectItem(object,"db_password"); 22 printf("db_password:%s\n",item->valuestring); 23 24 item = cJSON_GetObjectItem(object,"db_type"); 25 printf("db_type:%s\n",item->valuestring); 26 27 item = cJSON_GetObjectItem(object,"db_ip"); 28 printf("db_ip:%s\n",item->valuestring); 29 30 item = cJSON_GetObjectItem(object,"db_port"); 31 printf("db_port:%s\n",item->valuestring); 32 33 item = cJSON_GetObjectItem(object,"db_name"); 34 printf("db_name:%s\n",item->valuestring); 35 36 item = cJSON_GetObjectItem(object,"sql"); 37 printf("db_sql:%s\n",item->valuestring); 38 39 40 /*這里這個是直接可以獲取值的*/ 41 arrayItem = cJSON_GetObjectItem(json,"syslog_enable"); 42 printf("%s\n",arrayItem->valuestring); 43 } 44 } 45 cJSON_Delete(json); 46 close(fp); 47 }
執行的結果如下:

