对于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 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 } 执⾏的结果如下: 因篇幅问题不能全部显示,请点此查看更多更全内容