赞
踩
使用C语言解析json文件,使用过几次每次都要查资料,所以写个帖子以后再碰到就不用花太多时间了,有兴趣的同学可以简单借鉴
可以访问这位大佬的这篇文章
https://blog.csdn.net/nanfeibuyi/article/details/86605234
直面大佬
我用大佬的方法编译链接库的时候出现过一点问题,这里也记录一下
https://blog.csdn.net/yjk13703623757/article/details/53217377
直面大佬
我用的是文章中的第二个方法将解压文件夹中的文件放到
/usr/loca/lib
后面的步骤按链接文章中的操作就行了
如果不想要链接库的话可以下载这个文件
cJSON库https://sourceforge.net/projects/cjson/
里面有.c和.h文件编译的时候放到一起就行了
里面的函数和cJSON库中的函数是一样的,只是使用起来不需要配置和链接库
这里在贴个大佬的连接,讲的十分详细
https://blog.csdn.net/Mculover666/article/details/103796256
直面大佬
这个也是参考大佬的, 可装也可以不用装,效果如下:
这是大佬的链接:https://linux.cn/article-12915-1.html
添加链接描述
1. 将json文件解析成cJSON对象后,cJSON内部使用链表的方式存储键值对,所以使用后需要及时释放内存
2. typedef struct cJSON {
struct cJSON *next,*prev; // 用于链表的构建
struct cJSON *child;
int type; // 记录当前cJSON结构体存放的类型(cJSON_Object、cJSON_Array、cJSON_String、cJSON_Number、cJSON_NULL、cJSON_True、cJSON_False)
char *valuestring; // 存放字符串值
int valueint; // 存放整型值
double valuedouble; // 存放浮点型值
char *string; // 存放键名
} cJSON;
#include <stdio.h> #include <string.h> #include <stdlib.h> #include "cJSON.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <unistd.h> // #define WRITE_ // #define READ_ // #define CHANG_ int main(void) { //编辑json文件内容 #ifdef WRITE_ //打开json文件并创建数据 //创建一个空的文档对象 cJSON* json = cJSON_CreateObject(); //向文档中增加一个键值对{"name":"zww"} cJSON_AddItemToObject(json, "name", cJSON_CreateString("calmReed")); cJSON_AddItemToObject(json, "age", cJSON_CreateNumber(20)); //宏的使用 效果和上面的一样,只是看起来更简短 cJSON_AddNumberToObject(json, "score", 12); cJSON_AddStringToObject(json, "address", "jiangxi"); cJSON* array = NULL; //数组 cJSON_AddItemToObject(json, "love", array = cJSON_CreateArray()); //创建一个数组到json这个类中 //创建一个对象 cJSON *myjson = cJSON_CreateObject(); //创建键值对到对象中 cJSON_AddItemToObject(myjson, "who", cJSON_CreateString("me")); //在数组中添加一个对象 cJSON_AddItemToArray(array, myjson); //向数组中添加一个数字 cJSON_AddItemToArray(array, cJSON_CreateNumber(20)); //将json结构体格式化到缓冲区 char *buf = cJSON_Print(json); //打开文件用以写入json数据 FILE *fp = fopen("test2.json", "w"); fwrite(buf, 1, strlen(buf), fp); // 使用之后注意释放字符串内存 free(buf); fclose(fp); //释放json结构体所占的内存 cJSON_Delete(json); #endif //读取json文件内容 #ifdef READ_ //打开文件并读取数据 //打开保存JSON数据的文件 int fd = open("test2.json",O_RDWR); if(fd < 0) { perror("open fail\n"); return -1; } //读取文件中的数据 char buf[2048]={0}; int ret = read(fd, buf, sizeof(buf)); if(ret == -1) { perror("read error"); return -1; } close(fd); //把该字符串数据转换成JSON数据(对象) 开始的对象为最外层的对象 cJSON *root=cJSON_Parse(buf); if(root == NULL) { printf("parse error\n"); return -1; } /* * 取对象中的value值 * */ cJSON *_name = cJSON_GetObjectItem(root,"name");//获取键"name"对应的JSON值 if(_name == NULL) { printf("GetObjec error\n"); return -1; } // 如果单纯只是为了打印,直接使用_name->valuestring就行 char *_name_c = (char *)malloc(strlen(_name->valuestring)+1); strcpy(_name_c, _name->valuestring); printf("name = [%s]\n", _name_c); free(_name_c); /* * 获取数组中的内容 * * */ //当前的value1 是一个数组对象 cJSON * _love = cJSON_GetObjectItem(root,"love"); if(_love == NULL) { printf("GetObjectItem error\n"); return -1; } //获取该数组对象的大小 int _len = cJSON_GetArraySize(_love); printf("love arry len = %d\n",_len); //根据下标获取对象 int i = 0; cJSON * type_value = NULL; for(i=0;i<_len;i++) { //获取数组中的每个内容, 如果对象则进一步解析 type_value = cJSON_GetArrayItem(_love,i); if(type_value == NULL) { printf("GetObjectItem error\n"); return -1; } if(type_value->type == cJSON_Object) { cJSON *_who = cJSON_GetObjectItem(type_value, "who"); printf("love[%d]=%s\n",i, _who->valuestring); } if(type_value->type == cJSON_Number) { printf("love[%d]=%d\n",i, type_value->valueint); } } cJSON_Delete(root); #endif #ifdef CHANG_ /* extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); */ //修改数据并保存 int fd = open("test2.json",O_RDWR); if(fd < 0) { perror("open fail\n"); return -1; } //读取文件中的数据 char buf[2048]={0}; int ret = read(fd, buf, sizeof(buf)); if(ret == -1) { perror("read error"); return -1; } lseek(fd, 0, SEEK_SET);//注意将fd放到开头 //把该字符串数据转换成JSON数据(对象) 开始的对象为最外层的对象 cJSON *root=cJSON_Parse(buf); if(root == NULL) { printf("parse error\n"); return -1; } //修改值 cJSON_ReplaceItemInObject(root, "name",cJSON_CreateString("calm_reed")); cJSON_ReplaceItemInObject(root, "age",cJSON_CreateNumber(11)); //修改数组中的对象的值 cJSON *arry_love = cJSON_GetObjectItem(root,"love"); cJSON *type_who = cJSON_GetArrayItem(arry_love, 0); cJSON_ReplaceItemInObject(type_who, "who",cJSON_CreateString("you")); // 直接修改cJSON中的值也是可以的, 需要注意的是如果是整型,需要用valuedouble才能修改成功 // cJSON *value_num = cJSON_GetArrayItem(arry_love, 1); // value_num->valuedouble = 111; //将json结构体格式化到缓冲区 char *_out = cJSON_Print(root); strcpy(buf, _out); //将修改后的数据写入到文件中 write(fd, buf, strlen(buf)); free(_out); close(fd); //释放json结构体所占的内存 cJSON_Delete(root); #endif return 0; }
//#define WRITE_ //写
//#define READ_ //读
//#define CHANG_ //改
流程:
1.创建cJSON *对象 ->
2.使用json库中的函数创建信息 ->
3.将对象转换为字符串格式 ->
4.将字符串写入到文件中
上面的代码已经将大部分的种类创建列举出来了,其他的创建也是大同小异
需要注意的是 :
1.数组中似乎只能创建key没有value, 如果要键值对的话,需要在数组中创建对象
2.需要及时释放内存cJSON_Delete
流程:
1.打开文件 ->
2.将文件内容放到字符串中 ->
3.将字符串转换为cJSON *对象 ->
4.使用json库中的函数获取需要的信息
运行结果
name = [calmReed]
love arry len = 2
love[0]=me
love[1]=20
读取和添加也差不多只不过是函数从Add变成了Get
如果有多层嵌套的解析也是如此,一层一层的获取
流程:
1.打开文件 ->
2.将文件内容放到字符串中 ->
3.将字符串转换为cJSON *对象 ->
4.使用json库中的函数修改信息
运行结果
原来的内容
```php
{
"name": "calmReed",
"age": 20,
"score": 12,
"address": "jiangxi",
"love": [{
"who": "me"
}, 20]
}
修改后的内容
{
"name": "calm_reed",
"age": 11,
"score": 12,
"address": "jiangxi",
"love": [{
"who": "you"
}, 20]
}
1.修改json文件内容简单来说就是覆盖原有文件中的内容,但我们已经将所有文件内容复制到了字符串中,需要将文件描述符放到文件的开头,否则就不是修改而是追加了 2.cJSON_Print()所返回的指针源码中是使用malloc申请过内存的,所以使用之后需要free()释放 3.关于修改的函数问题: https://blog.csdn.net/Mculover666/article/details/103796256 这篇文章中的第二点 /* * String:用于表示该键值对的名称; type:用于表示该键值对中值的类型; valuestring:如果键值类型(type)是字符串,则将该指针指向键值; valueint:如果键值类型(type)是整数,则将该指针指向键值; valuedouble:如果键值类型(type)是浮点数,则将该指针指向键值; * */ 可以通过修改结构体中的内容来修改键值,使用源码提供的函数其内部是将原来链表中的节点(需要修改的节点)进行了删除,然后重新创建了一个节点替换上去
本文章主要面向于如何使用 cJSON库中的内容,并不深入,如果需要深入的了解可以查看文首的大佬链接,这是本人的第一篇文章,如果有什么错误希望大家能及时回复,希望对大家有帮助
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。