Linux(程序设计):30---cJSON库(C语言操作JSON)

丈夫欲遂平生志,一载寒窗一举汤。这篇文章主要讲述Linux(程序设计):30---cJSON库(C语言操作JSON)相关的知识,希望能为你提供帮助。
一、cJSON库概述

  • JSON语法介绍可以参阅:javascript:void(0)
  • cJSON开发库是C语言提供的对JSON操作的API
cJSON库的编译安装
  • 下载cJSON源码
git clone https://github.com/DaveGamble/cJSON.git

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 下载完成之后有一个cJSON目录
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 下载完成之后进入cJSON目录,在里面建立一个build目录,然后进入build目录,输入cmake ..
cd cJSONmkdir buildcd buildcmake ..

【Linux(程序设计):30---cJSON库(C语言操作JSON)】
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 然后回到顶级目录,可以看到目录下生成了一个Makefile文件,此时输入make对cJOSN进行编译
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 编译完成之后进行安装
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 默认情况下,cJSON的头文件安装到/usr/local/include/cjson/目录下,动态库文件安装到/usr/local/lib/目录下,相关cmake文件安装到/usr/local/lib/cmake/cJSON/目录下
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 因为头文件默认安装在/usr/local/include/cjson/目录下,因此编译程序的时候如果用到cJSON.h这个头文件会显示不存在,如下图所示
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 因此我们需要将/usr/local/include/cjson/cJSON.h移动到/usr/local/include/目录下,如下所示
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 备注:其实我们不需要将cJSON.h文件从/usr/local/include/cjson/目录下移动到/usr/local/include/目录下,如果不移动的话那么就编写代码时带上include "cjson/cJSON.H"头文件即可,只不过有cjson/前缀比较麻烦
编译运行带有cJSON库的程序
  • 有两种方式:
    • ①方式一:像上面一样,将cJSON安装,然后将cJONS.h拷贝到/usr/local/include/目录下,然后将源码目录下的cJOSN.c文件拷贝到项目目录下
    • ②方式二:不用像上面一样安装cJSON,直接将cJSON源码目录下的cJSON.h和cJSON.c文件拷贝到项目下就可以编译使用了
  • 编译程序时使用下面的命令:
# 因为cJSON源码中使用到了数学函数库, 因此需要使用-lm选项 gcc cJSON.c demo.c -o demo -lm

  • 编译的过程中可能会遇到的问题:
    • 遇到cJSON.h头文件不识别的问题:确保cJSON.h位于你的程序可以找到的地方,如果在其他地方可以指定gcc -I参数进行编译
    • 不仅要有cJSON.h头文件,程序编译时还要需要cJSON.c文件,因此需要将cJSON库下的cJSON.c拷贝到自己的项目中进行编译
    • cJSON不同版本之间源码不同,因此需要确保使用的cJSON.h和cJSON.c是同一版本的,否则会编译不通过
二、cJSON库重要的数据结构与类型
cJSON结构
  • cJSON结构定义在cJSON.h头文件中,每个JSON对象就是用这个结构表示的
/* The cJSON structure: */ 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. */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;

  • next、prev:用于遍历数组或对象链的前后向后链表指针
  • child:指向数组或对象的孩节点
  • type:代表一个JSON是value的类型
  • valuestring:如果value是字符串类型,则该值指向于value
  • valueint:如果value是整数类型,则该值指向于value
  • valuedouble:如果value是浮点数类型,则该值指向于value
  • string是key的名字
cJSON支持的类型
  • 下面是一些宏定义,就是cJOSN结构中type字段可以取得值,代表值的类型
/* cJSON Types: */ #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

三、重点函数
cJSON_Parse
cJSON *cJSON_Parse(const char *value);

  • 作用:参数传递一个JSON字符串,将该字符串转换为一个cJSON对象进行返回(该对象是在内存中动态申请的,因此需要用下面的cJSON_Delete进行释放)
  • 返回值:
    • 成功:返回一个指向内存中的cJSON的指针
    • 失败:返回NULL
cJSON_Delete
void cJSON_Delete(cJSON *c);

  • 作用:释放位于堆中的cJSON结构体内存
  • 无返回值
  • 备注:
    • 在使用cJSON_Parse创建cJSON对象之后,如果该对象不再使用了,需要释放该对象,否则导致内存泄漏
    • 其他有些API也会创建cJSON对象,在申请用完之后也需要释放
cJSON_Print
char*cJSON_Print(cJSON *item);

  • 作用:将cJSON对象解析成一个字符串进行返回,并在堆中开辟一块char*的内存空间存储该字符串
  • 返回值:
    • 成功:返回一个指向char*指针指向位于堆中的JSON字符串
    • 失败:返回NULL
  • 备注:
    • 通过cJSON_Print()可以将cJSON链表中所有的cJSON对象打印出来
    • cJSON_PrintUnformatted()与 cJSON_Print()类似,只是打印输出不带格式,而只是一个 字符串数据
    • 因为返回值是该函数自动申请的,因此在使用完之后需要使用free()释放该函数返回值的内存空间
cJSON_Version
const char* cJSON_Version(void);

  • 作用:将返回当前使用的cJSON库的版本号
  • 返回值:一个表示当前版本的字符串
cJSON_GetArrayItem
cJSON *cJSON_GetArrayItem(cJSON *array,int item);

  • 作用:如果array是一个数组类型的,则返回数组中item索引处的cJSON对象
  • 返回值:
    • 成功:返回一个指向cJSON类型的结构体指针
    • 失败:返回NULL
cJSON_GetArraySize
int cJSON_GetArraySize(cJSON *array);

  • 作用:如果array是一个数组类型,返回数组中对应元素的个数
  • 返回值:
    • 有元素:返回元素的个数
    • 无元素:返回0
  • 与上面类似的接口还有cJSON_GetObjectItem()和cJSON_HashObjectItem()
四、所有函数简介
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

五、演示案例1
  • 下面的demo1.c演示对cJSON的增删改查,以及将JSON内容写入demo1.json文件中
  • Github源码链接: https://github.com/dongyusheng/csdn-code/tree/master/cJSON/demo1
代码如下
//demo1.c #include < stdio.h> #include < stdlib.h> #include "cJSON.h" #include < string.h> /** { "name": "milo", "age": 80, "professional": {专业 "english": 4, "putonghua": 2, "computer": 4 }, "languages": ["C++", "C"], "phone": { "number": "18620823143", "type": "home" }, "courses": [{ "name": "Linux kernel development", "price": "7.7" }, { "name": "Linux server development", "price": "8.0" }], "vip": true, "address": null } *///打印CJSON void printfJson(cJSON *json) { if (NULL == json) { return; } char *cjson=cJSON_Print(json); //深拷贝 printf("json:%s\\n", cjson); free(cjson); }//释放 void freeJson(cJSON *json) { if (json != NULL) { cJSON_Delete(json); } }//创建JSON cJSON * createJson() { //创建根节点JSON(最外面大括号的JSON对象) cJSON *json_root=cJSON_CreateObject(); cJSON_AddItemToObject(json_root, "name", cJSON_CreateString("milo")); cJSON_AddNumberToObject(json_root, "age", 80); //下面是4个内部JSON对象(包含在根JSON内部的) cJSON *json_professional=cJSON_CreateObject(); cJSON_AddItemToObject(json_professional,"english", cJSON_CreateNumber(4)); cJSON_AddItemToObject(json_professional,"putonghua", cJSON_CreateNumber(2)); cJSON_AddItemToObject(json_professional,"computer", cJSON_CreateNumber(3)); cJSON *json_languages=cJSON_CreateArray(); //注意: 这是一个数组 cJSON_AddItemToArray(json_languages, cJSON_CreateString("C++")); cJSON_AddItemToArray(json_languages, cJSON_CreateString("C")); cJSON *json_phone=cJSON_CreateObject(); cJSON_AddItemToObject(json_phone,"number", cJSON_CreateString("18620823143")); cJSON_AddItemToObject(json_phone,"type", cJSON_CreateString("home")); cJSON *json_courses = cJSON_CreateArray(); //注意: courses也是一个数组, 其内部有两个对象 cJSON* json_pItem1 = cJSON_CreateObject(); cJSON_AddItemToObject(json_pItem1, "name", cJSON_CreateString("Linux kernel development")); cJSON_AddNumberToObject(json_pItem1, "price", 7.7); cJSON_AddItemToArray(json_courses, json_pItem1); cJSON* json_pItem2 = cJSON_CreateObject(); cJSON_AddItemToObject(json_pItem2, "name", cJSON_CreateString("Linux server development")); cJSON_AddNumberToObject(json_pItem2, "price", 8.8); cJSON_AddItemToArray(json_courses, json_pItem2); //将这个几个内部JSON添加到根节点JSON对象中 cJSON_AddItemToObject(json_root, "professional", json_professional); cJSON_AddItemToObject(json_root, "languages", json_languages); cJSON_AddItemToObject(json_root, "phone", json_phone); cJSON_AddItemToObject(json_root, "courses", json_courses); cJSON_AddBoolToObject(json_root, "vip", 1); cJSON_AddNullToObject(json_root, "address"); return json_root; }//向已有的cJSON对象中添加数据(此函数以添加到根节点为例) //如果要添加到根cJSON对象内部的cJSON对象中(例如添加到professional中), 需要解析cJSON对象, 可以参阅下面的analysisJsonObj()函数 //"hobby": ["Basketball", "Football", "badminton"], void addDataToJson(cJSON *json) { if (NULL == json) { return; }cJSON *hobby=cJSON_CreateArray(); cJSON_AddItemToArray(hobby, cJSON_CreateString("Basketball")); cJSON_AddItemToArray(hobby, cJSON_CreateString("Football")); cJSON_AddItemToArray(hobby, cJSON_CreateString("badminton")); /* CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); */ cJSON_AddItemToObject(json, "hobby", hobby); printfJson(json); }//修改cJSON对象 //例如将 "hobby": ["Basketball", "Football", "badminton"], 修改为"hobby": ["Skating", "dance"], void updateDataToJson(cJSON *json) { if (NULL == json) { return; }cJSON *hobby=cJSON_CreateArray(); cJSON_AddItemToArray(hobby, cJSON_CreateString("Skating")); cJSON_AddItemToArray(hobby, cJSON_CreateString("dance")); /* CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); */ //修改替换 cJSON_ReplaceItemInObject(json, "hobby", hobby); printfJson(json); }//删除 //例如删除"hobby": ["Skating", "dance"], void deleteDataToJson(cJSON *json) { if (NULL == json) { return; }/* CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); */ cJSON_DetachItemFromObject(json, "hobby"); printfJson(json); }//解析JSON void analysisJsonObj(cJSON *json) { if (NULL == json) { return; } //解析name cJSON *json_name = cJSON_GetObjectItem(json, "name"); printf("root[%s:%s]\\n", json_name-> string, json_name-> valuestring); //解析age cJSON *json_age = cJSON_GetObjectItem(json, "age"); printf("root[%s:%d]\\n", json_age-> string, json_age-> valueint); //解析professional, 通过调用child和next遍历解析 cJSON *json_professional = cJSON_GetObjectItem(json, "professional"); cJSON *json_professional_child = json_professional-> child; while (json_professional_child != NULL) { printf("%s[%s:%d]\\n", json_professional-> string, json_professional_child-> string, json_professional_child-> valueint); json_professional_child = json_professional_child-> next; } //解析languages, 注意languages是一个数组 cJSON *json_languages = cJSON_GetObjectItem(json, "languages"); if (json_languages) { int size = cJSON_GetArraySize(json_languages); printf("%s size:%d\\n", json_languages-> string, size); for (int i = 0; i < size; i++) { cJSON *json_languages_child =cJSON_GetArrayItem(json_languages, i); printf("%s[%d:%s]\\n", json_languages-> string, i, json_languages_child-> valuestring); } } //解析phone. 另一种方式解析, 直接通过名字获取 cJSON *json_phone = cJSON_GetObjectItem(json, "phone"); cJSON *json_phone_number = cJSON_GetObjectItem(json_phone,"number"); cJSON *json_phone_type = cJSON_GetObjectItem(json_phone,"type"); printf("%s[%s:%s]\\n", json_phone-> string, json_phone_number-> string, json_phone_number-> valuestring); printf("%s[%s:%s]\\n", json_phone-> string, json_phone_type-> string, json_phone_type-> valuestring); //解析courses cJSON *json_courses = cJSON_GetObjectItem(json, "courses"); if (json_courses) { int size = cJSON_GetArraySize(json_courses); printf("%s size:%d\\n", json_courses-> string, size); for(int i=0; i< size; i++) { cJSON *json_array = cJSON_GetArrayItem(json_courses, i); if (json_array) { cJSON *json_course_name = cJSON_GetObjectItem(json_array,"name"); cJSON *json_course_price = cJSON_GetObjectItem(json_array,"price"); printf("%s[%s:%.1lf]\\n", json_courses-> string, json_course_name-> string, json_course_name-> valuedouble); printf("%s[%s:%.1lf]\\n", json_courses-> string, json_course_price-> string, json_course_price-> valuedouble); } } } //解析vip, vip是布尔值, 有两种方式解析获取 cJSON *json_vip = cJSON_GetObjectItem(json, "vip"); /* if (json_vip-> type == cJSON_True) { printf("root[%s:true]\\n", json_vip-> string); } else if (json_vip-> type == cJSON_False) { printf("root[%s:false]\\n", json_vip-> string); } else { printf("root[%s:false]\\n", json_vip-> string); } */ cJSON_bool bvip = cJSON_IsBool(json_vip); if (bvip == cJSON_True) {//cJSON_False printf("root[%s:true]\\n", json_vip-> string); } else { printf("root[%s:false]\\n", json_vip-> string); } //解析address cJSON *json_address = cJSON_GetObjectItem(json, "address"); if (json_address-> type ==cJSON_NULL) { printf("root[%s:null]\\n", json_address-> string); } }//获取cJSON对象的类型, 并同时打印值 static void printJsonObjvalue(const cJSON *json) { if (NULL == json) { printf("NULL object!\\n"); return; }switch (json-> type) { case cJSON_False: printf("%s: false\\n", json-> string); break; case cJSON_True: printf("%s: true\\n", json-> string); break; case cJSON_NULL: printf("%s: cJSON_NULL\\n", json-> string); break; case cJSON_Number: printf("%s: %d, %f\\n", json-> string, json-> valueint, json-> valuedouble); break; case cJSON_String: printf("%s: %s\\n", json-> string, json-> valuestring); break; case cJSON_Array: printf("%s: cJSON_Array\\n", json-> string); break; case cJSON_Object: printf("%s: cJSON_Object\\n", json-> string); break; default: printf("unknown type\\n"); break; } }void analysisJsonPrint(cJSON *json) { if (NULL == json) { return; }cJSON *json_name = cJSON_GetObjectItem(json, "name"); printJsonObjvalue(json_name); cJSON *json_age = cJSON_GetObjectItem(json, "age"); printJsonObjvalue(json_age); cJSON *json_professional = cJSON_GetObjectItem(json, "professional"); cJSON *json_professional_child = json_professional-> child; while (json_professional_child != NULL) { printJsonObjvalue(json_professional_child); json_professional_child = json_professional_child-> next; }cJSON *json_languages = cJSON_GetObjectItem(json, "languages"); if (NULL == json_languages) { int size = cJSON_GetArraySize(json_languages); printf("%s size:%d\\n", json_languages-> string, size); for (int i = 0; i < size; i++) { cJSON *json_languages_child = cJSON_GetArrayItem(json_languages, i); printJsonObjvalue(json_languages_child); } }cJSON *json_phone = cJSON_GetObjectItem(json, "phone"); cJSON *json_phone_number = cJSON_GetObjectItem(json_phone,"number"); cJSON *json_phone_type = cJSON_GetObjectItem(json_phone,"type"); printJsonObjvalue(json_phone_number); printJsonObjvalue(json_phone_type); cJSON *json_courses = cJSON_GetObjectItem(json, "courses"); if (json_courses) { int size = cJSON_GetArraySize(json_courses); printf("%s size:%d\\n", json_courses-> string, size); for(int i=0; i< size; i++) { cJSON *arrayItem = cJSON_GetArrayItem(json_courses, i); if (NULL != arrayItem) { cJSON *json_course_name = cJSON_GetObjectItem(arrayItem,"name"); cJSON *json_course_price = cJSON_GetObjectItem(arrayItem,"price"); printJsonObjvalue(json_course_name); printJsonObjvalue(json_course_price); } } }cJSON *json_vip = cJSON_GetObjectItem(json, "vip"); printJsonObjvalue(json_vip); cJSON *json_address = cJSON_GetObjectItem(json, "address"); printJsonObjvalue(json_address); }//读取JSON cJSON* readJsonFile(char *fileName) { if (NULL == fileName) { return NULL; }FILE *fp = NULL; cJSON *json = NULL; char line[1024] = {0}; char *data = https://www.songbingjia.com/android/NULL; //打开一个文本文件,文件必须存在,只允许读 fp = fopen(fileName,"r"); if (NULL != fp) { //seek末尾 fseek(fp, 0, SEEK_END); //读取文件大小 long len = ftell(fp); //seek起始位值 fseek(fp, 0, SEEK_SET); data = https://www.songbingjia.com/android/(char*)malloc(len + 1); fread(data, 1, len, fp); fclose(fp); }printf("readJsonFile data:%s\\n", data); cJSON *json_root = cJSON_Parse(data); if (NULL == json_root) { printf("cJSON_Parse error:%s\\n", cJSON_GetErrorPtr()); }if (NULL != data) { free(data); }return json_root; }//保存JSON void writeJsonFile(char *fileName, cJSON *json) { if (NULL == json || NULL == fileName) { return; }char *cjson=cJSON_Print(json); FILE *fp = NULL; //新建一个文本文件,已存在的文件将内容清空,允许读写 fp = fopen(fileName, "w+"); if (NULL != fp) { fwrite(cjson, strlen(cjson),1,fp); fclose(fp); }if (NULL != cjson) { free(cjson); } }void test1() { cJSON *json_root = createJson(); //打印 printfJson(json_root); //解析json analysisJsonObj(json_root); //解析json analysisJsonPrint(json_root); freeJson(json_root); }void test2() { char *fileName = "./person.json"; //读取json cJSON *json_root = readJsonFile(fileName); //解析json analysisJsonObj(json_root); //解析json analysisJsonPrint(json_root); //写入json文件 writeJsonFile(fileName, json_root); //释放 freeJson(json_root); }//增删改 void test3() { cJSON *json_root = createJson(); addDataToJson(json_root); updateDataToJson(json_root); deleteDataToJson(json_root); freeJson(json_root); }int main(int argc, char *argv[]) {printf("-----------------------------------\\n"); test1(); printf("-----------------------------------\\n"); test2(); printf("-----------------------------------\\n"); test3(); printf("-----------------------------------\\n"); return 0; }

  • 编译如下:
gcc cJSON.c demo1.c -o demo1 -lm

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 效果如下(只截取部分):
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

六、演示案例2
  • 下面的comment_test.c演示从当前目录下的comment.json文件中读取JSON数据,并且将数据写入comment.json文件中
  • Github源码链接: https://github.com/dongyusheng/csdn-code/tree/master/cJSON/comment_test.c
代码如下
//comment_test.c #include < stdio.h> #include < stdlib.h> #include < sys/time.h> #include "cJSON.h" #include < string.h> //评论 typedef struct COMMENT { int user_id; int msg_id; char* comment; int click_count; int like_count; int reply_count; int is_new_reply; long add_time; } COMMENT; //例如 /** json对象 { "user_id":1, "msg_id":1, "comment":"json", "click_count":0, "like_count":0, "reply_count":0, "is_new_reply":0, "add_time":0, } *///获取当前时间毫秒数 long getCurrentTime() { struct timeval tv; gettimeofday(& tv,NULL); //毫秒 long time_sec = tv.tv_sec*1000 + tv.tv_usec/1000; return time_sec; }//打印CJSON void printfJson(cJSON *json) { if (NULL == json) { return; } char *cjson=cJSON_Print(json); //深拷贝 printf("json:%s\\n", cjson); free(cjson); //因为调用了cJSON_Print(), 因此需要手动释放资源 }void freeComment(COMMENT *comment) { if (comment != NULL) { if (comment-> comment != NULL) { free(comment-> comment); comment-> comment = NULL; }free(comment); comment = NULL; } }void freeJson(cJSON *json) { if (json != NULL) { cJSON_Delete(json); } }//将结构体转成cJSON cJSON *convertToJson(COMMENT *comment) { if (comment == NULL) return NULL; //创建json cJSON *json=cJSON_CreateObject(); //将 "user_id" 添加到 "json" 节点 cJSON_AddNumberToObject(json, "user_id", comment-> user_id); cJSON_AddNumberToObject(json, "msg_id", comment-> msg_id); cJSON_AddItemToObject(json, "comment", cJSON_CreateString(comment-> comment)); //调用cJSON_CreateString()将字符串转换为JSON中的字符串类型,否则报错 cJSON_AddNumberToObject(json, "click_count", comment-> click_count); cJSON_AddNumberToObject(json, "like_count", comment-> like_count); cJSON_AddNumberToObject(json, "reply_count", comment-> reply_count); cJSON_AddNumberToObject(json, "is_new_reply", comment-> is_new_reply); cJSON_AddNumberToObject(json, "add_time", comment-> add_time); //user_id等的value都是int类型的,因此使用cJSON_AddNumberToObject. 而comment是字符串类型的,因此使用cJSON_AddItemToObjectreturn json; }//解析cJSON对象, 将cJSON赋值给结构体 COMMENT* convertToComment(cJSON *json) { if (NULL == json) { return NULL; }//通cJSON对象中获取内容 cJSON *json_user_id = cJSON_GetObjectItem(json, "user_id"); cJSON *json_msg_id = cJSON_GetObjectItem(json, "msg_id"); cJSON *json_comment = cJSON_GetObjectItem(json, "comment"); cJSON *json_click_count = cJSON_GetObjectItem(json, "click_count"); cJSON *json_like_count = cJSON_GetObjectItem(json, "like_count"); cJSON *json_reply_count = cJSON_GetObjectItem(json, "reply_count"); cJSON *json_is_new_reply = cJSON_GetObjectItem(json, "is_new_reply"); cJSON *json_add_time = cJSON_GetObjectItem(json, "add_time"); //将内容赋值给结构体 COMMENT *comment = (COMMENT *)malloc(sizeof(COMMENT)); comment-> user_id = json_user_id-> valueint; //user_id等是使用int来存储的, 因此使用cJSON对象的valueint成员来获取(下同) comment-> msg_id = json_msg_id-> valueint; comment-> comment=(char *)malloc(256); memset(comment-> comment, 0, 256); strcat(comment-> comment, json_comment-> valuestring); //comment是使用字符串来存储的, 因此使用cJSON对象的valuestring成员来获取(下同) comment-> click_count = json_click_count-> valueint; comment-> like_count = json_like_count-> valueint; comment-> reply_count = json_reply_count-> valueint; comment-> is_new_reply = json_is_new_reply-> valueint; comment-> add_time = (long)(json_add_time-> valuedouble); //C中使用long来存储时间, 在cJSON中使用double来存储return comment; }//从数据中读取数据 void readJsonFromData(char *data) { cJSON *json=cJSON_Parse(data); //将data数据构建成cJSON结构 //打印json printfJson(json); COMMENT* comment = convertToComment(json); if (comment != NULL) {comment-> like_count = 77; comment-> reply_count = 99; //转为json cJSON *childjson = convertToJson(comment); //打印json printfJson(childjson); //释放对象 freeComment(comment); // freeJson(childjson); } //cJSON_Parse()返回的cJSON对象需要手动释放资源 freeJson(json); }//保存JSON void writeJsonFile(cJSON *json) { if (NULL == json) { return; }char *cjson=cJSON_Print(json); FILE *fp = NULL; char *fileName = "./comment.json"; fp = fopen(fileName, "w+"); if (NULL != fp) { fwrite(cjson, strlen(cjson),1,fp); fclose(fp); } if (cjson != NULL) { free(cjson); } }//读取JSON void readJsonFile() { FILE *fp = NULL; char *out; char line[1024] = {0}; char *fileName = "./comment.json"; //打开一个文本文件,文件必须存在,只允许读 fp = fopen(fileName, "r"); //seek末尾 fseek(fp, 0, SEEK_END); //读取文件大小 long len = ftell(fp); //seek起始位值 fseek(fp, 0, SEEK_SET); char *data = https://www.songbingjia.com/android/(char*)malloc(len + 1); fread(data, 1, len, fp); if (fp != NULL) { fclose(fp); }//读取 readJsonFromData(data); if (NULL != data) { free(data); } }COMMENT *createComment() { COMMENT *comment = (COMMENT *)malloc(sizeof(COMMENT)); comment-> user_id = 1; comment-> msg_id = 10000; comment-> comment=(char *)malloc(256); memset(comment-> comment, 0, 256); sprintf(comment-> comment,"我赞同楼主"); comment-> click_count = 0; comment-> like_count = 0; comment-> reply_count = 0; comment-> is_new_reply = 0; comment-> add_time = getCurrentTime(); return comment; }void test1() { COMMENT *comment = createComment(); //转为json cJSON *json = convertToJson(comment); //保存json writeJsonFile(json); freeComment(comment); freeJson(json); }void test2() { //读取json readJsonFile(); }int main(int argc, char *argv[]) {test1(); test2(); return 0; }

  • 编译如下:
gcc cJSON.c comment_test.c -o comment_test -lm

Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片

  • 效果如下:
Linux(程序设计):30---cJSON库(C语言操作JSON)

文章图片


    推荐阅读