对于 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"
- }
三个大的对象分别有两个是数组一个是直接可以获取的. 代码如下:
- #include <stdio.h>
- #include "cJSON.h"
- int main() {
- FILE *fp = NULL;
- cJSON *json;
- char *out;
- char line[1024] = {0};
- if(NULL != (fp = fopen("./test.ply", "r"))) {
- while (NULL != fgets(line, sizeof(line), fp)) {
- json=cJSON_Parse(line); // 获取整个大的句柄
- out=cJSON_Print(json); // 这个是可以输出的. 为获取的整个 json 的值
- cJSON *arrayItem = cJSON_GetObjectItem(json,"syslog_db"); // 获取这个对象成员
- cJSON *object = cJSON_GetArrayItem(arrayItem,0); // 因为这个对象是个数组获取, 且只有一个元素所以写下标为 0 获取
- /* 下面就是可以重复使用 cJSON_GetObjectItem 来获取每个成员的值了 */
- cJSON *item = cJSON_GetObjectItem(object,"db_user"); //
- printf("db_user:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"db_password");
- printf("db_password:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"db_type");
- printf("db_type:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"db_ip");
- printf("db_ip:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"db_port");
- printf("db_port:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"db_name");
- printf("db_name:%s\n",item->valuestring);
- item = cJSON_GetObjectItem(object,"sql");
- printf("db_sql:%s\n",item->valuestring);
- /* 这里这个是直接可以获取值的 */
- arrayItem = cJSON_GetObjectItem(json,"syslog_enable");
- printf("%s\n",arrayItem->valuestring);
- }
- }
- cJSON_Delete(json);
- close(fp);
- }
执行的结果如下:
来源: https://www.cnblogs.com/piaoyang/p/9274925.html