c++之json的创建,解析,增加,删除

c++之json的创建,解析,增加,删除

    • 1.存储方式,类型
    • 2.宏
    • 3.创建,保存json
    • 4.解析
    • 5.删除
    • 6.修改

1.存储方式,类型

typedef struct cJSON {
struct cJSON *next,prev;    / next是获取下一个元素数据,prev是获取前一个元素数据 */
struct cJSON child;        / 获取第一个元素数据,当需要获取下一个时,就得使用next了. */
int type;                    /* 当前的json类型对象、数组、字符串、数字、null、true、false等 */char *valuestring;            /* 字符串值, if type==cJSON_String */
int valueint;                /* 整形类型值, if type==cJSON_Number */
double valuedouble;            /* 浮点数类型值, if type==cJSON_Number */char *string;                /* 这个是键 */
} cJSON;

2.宏

/* cJSON Types: */
#define cJSON_False 0        // true
#define cJSON_True 1        // false
#define cJSON_NULL 2        // NULL
#define cJSON_Number 3        // 数字
#define cJSON_String 4        // 字符串
#define cJSON_Array 5        // 数组
#define cJSON_Object 6        // 对象

3.创建,保存json

#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>#include <sys/stat.h>    // 获取文件大小#include "cJSON.h"int main(){//1. 定义对象 { }cJSON* interest = cJSON_CreateObject();// 插入元素,对应 键值对cJSON_AddItemToObject(interest, "combat", cJSON_CreateString("热血"));        // 当值是字符串时,需要使用函数cJSON_CreateString()创建cJSON_AddItemToObject(interest, "reasoning", cJSON_CreateString("推理"));// 或者使用宏进行添加//cJSON_AddStringToObject(interest, "reasoning", "推理");    // 或者这样写// 2.定义 [ ] 数组cJSON* final = cJSON_CreateArray();// 往数组中添加元素cJSON_AddItemToArray(final, cJSON_CreateString("BE"));cJSON_AddItemToArray(final, cJSON_CreateString("HE"));// 3.定义 { } 对象cJSON* likeObject1 = cJSON_CreateObject();cJSON_AddItemToObject(likeObject1, "game", cJSON_CreateString("斩赤红之瞳"));cJSON_AddItemToObject(likeObject1, "Episodes", cJSON_CreateNumber(22));        // 当值是数字时,需要使用函数cJSON_CreateNumber()创建//cJSON_AddNumberToObject(likeObject1, "price", 66.6);    // 或者这样写cJSON* likeObject2 = cJSON_CreateObject();cJSON_AddItemToObject(likeObject2, "game", cJSON_CreateString("文豪野犬"));cJSON_AddItemToObject(likeObject2, "Episodes", cJSON_CreateNumber(84));// 4.定义 [ ] 数组cJSON* like = cJSON_CreateArray();// 往数组中添加元素cJSON_AddItemToArray(like, likeObject1);cJSON_AddItemToArray(like, likeObject2);// 定义 [ ] 数组cJSON* education1 = cJSON_CreateArray();cJSON_AddItemToArray(education1, cJSON_CreateString("战斗"));cJSON_AddItemToArray(education1, cJSON_CreateString("热血"));cJSON* education2 = cJSON_CreateArray();cJSON_AddItemToArray(education2, cJSON_CreateString("推理"));cJSON_AddItemToArray(education2, cJSON_CreateString("格斗"));// 5.定义 [ ] 数组/*"languages": {"serialOne": { "language": "汉语", "grade" : 10 },"serialTwo" : { "language": "英语", "grade" : 6}}*/cJSON* education = cJSON_CreateArray();cJSON_AddItemToArray(education, education1);cJSON_AddItemToArray(education, education2);// 定义对象 { }cJSON* serialOne = cJSON_CreateObject();cJSON_AddItemToObject(serialOne, "language", cJSON_CreateString("汉语"));cJSON_AddItemToObject(serialOne, "grade", cJSON_CreateNumber(10));cJSON* serialTwo = cJSON_CreateObject();cJSON_AddItemToObject(serialTwo, "language", cJSON_CreateString("英语"));cJSON_AddItemToObject(serialTwo, "grade", cJSON_CreateNumber(6));// 定义对象 { }cJSON* languages = cJSON_CreateObject();cJSON_AddItemToObject(languages, "serialOne", serialOne);cJSON_AddItemToObject(languages, "serialTwo", serialTwo);// 创建跟对象cJSON* root = cJSON_CreateObject();// 将子项插入根项中cJSON_AddItemToObject(root, "name", cJSON_CreateString("Blue"));cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(25));cJSON_AddItemToObject(root, "interest", interest);cJSON_AddItemToObject(root, "final", final);cJSON_AddItemToObject(root, "like", like);cJSON_AddItemToObject(root, "education", education);cJSON_AddItemToObject(root, "languages", languages);cJSON_AddItemToObject(root, "vip", cJSON_CreateTrue());    // "vip":    true        插入布尔类型数据需要使用cJSON_CreateBool函数cJSON_AddItemToObject(root, "address", cJSON_CreateNull());    // "address":    null    插入NULL值需要使用cJSON_CreateNull函数//cJSON_AddTrueToObject(root, "vip");//cJSON_AddNullToObject(root, "address");    // 或者这样写也是可以的// 控制台输出char* ALL_JSON = cJSON_Print(root);char* ALL_JSONUnformatted = cJSON_PrintUnformatted(root);printf("ALL_JSON:\n%s\n", ALL_JSON);        // ALL_JSON:有做格式调整printf("ALL_JSONUnformatted:\n%s\n", ALL_JSONUnformatted);    // cJSON_PrintUnformatted:没有做格式调整// 返回的字符串指针需要自己释放free(ALL_JSON);free(ALL_JSONUnformatted);//****************************************************************// 打开文件FILE* file = NULL;file = fopen("E:\\abs\\test.json", "w");    if (file == NULL) {printf("Open file fail!\n");// 释放指针内存cJSON_Delete(root);return;}char* cjValue = cJSON_Print(root);// 写入文件//int ret = fwrite(cjValue, sizeof(char), strlen(cjValue), file);int ret = fputs(cjValue, file);if (ret == EOF) {printf("写入文件失败!\n");}fclose(file);free(cjValue);// 释放指针内存cJSON_Delete(root);}

打印:
在这里插入图片描述

4.解析

#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>#include <sys/stat.h>    // 获取文件大小#include "cJSON.h"using namespace std;cJSON* item = NULL;
char* v_str = NULL;
double v_double = 0.0;
int v_int = 0;
bool v_bool = false;void main(){// 打开文件FILE* file = NULL;const char* FILE_NAME = "E:\\abs\\test.json";file = fopen(FILE_NAME, "r");if (file == NULL) {printf("Open file fail!\n");return;}// 获得文件大小struct stat statbuf;stat(FILE_NAME, &statbuf);int fileSize = statbuf.st_size;printf("文件大小:%d\n", fileSize);// 分配符合文件大小的内存char* jsonStr = (char*)malloc(sizeof(char) * fileSize + 1);memset(jsonStr, 0, fileSize + 1);// 读取文件中的json字符串int size = fread(jsonStr, sizeof(char), fileSize, file);if (size == 0) {printf("读取文件失败!\n");fclose(file);return;}//printf("%s\n", jsonStr);// 将读取到的json字符串转换成json变量指针cJSON* root = cJSON_Parse(jsonStr);if (!root) {printf("Error before: [%s]\n", cJSON_GetErrorPtr());free(jsonStr);return;}free(jsonStr);printf("*******************************1**************************************\n");// 1.解析:"name":    "blue",{item = cJSON_GetObjectItem(root, "name");if (item != NULL) {/* 写法一:*///判断是不是字符串类型if (item->type == cJSON_String) {v_str = cJSON_Print(item);        // 通过函数获取值printf("name = %s\n", v_str);free(v_str);                    // 通过函数返回的指针需要自行free,否则会导致内存泄漏v_str = NULL;}/* 写法二: */// 判断是不是字符串类型if (item->type == cJSON_String) {v_str = item->valuestring;        // 此赋值是浅拷贝,不需要现在释放内存printf("name = %s\n", v_str);}}}printf("*******************************2**************************************\n");// 2.解析:"age":    "23",{item = cJSON_GetObjectItem(root, "age");if (item != NULL) {    // 合法性检查if (item->type == cJSON_Number) {        // 判断是不是数字v_int = item->valueint;            // 获取值printf("age = %d\n", v_int);}}}printf("*******************************3**************************************\n");// 3.解析:"vip":    true,{item = cJSON_GetObjectItem(root, "vip");if (item != NULL) {if (item->type == cJSON_True || item->type == cJSON_False) {v_str = cJSON_Print(item);        // 由于bool类型结构体中没有给出,所以使用字符串代替printf("vip = %s\n", v_str);free(v_str);v_str = NULL;}}}printf("*******************************4**************************************\n");//4. 解析:"address":    null{item = cJSON_GetObjectItem(root, "address");if (item != NULL && item->type == cJSON_NULL) {v_str = cJSON_Print(item);        // 由于NULL类型结构体中没有给出,所以使用字符串代替printf("address = %s\n", v_str);free(v_str);v_str = NULL;}}printf("*******************************5**************************************\n");//5. 解析:"interest":    {"combat":    "热血","reasoning" : "推理"},{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "interest");        // 获取object对象名if (item != NULL) {cJSON* val = NULL;val = cJSON_GetObjectItem(item, "combat");    // 根据object对象名获得里面的basketball数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("combat = %s\n", v_str);}val = cJSON_GetObjectItem(item, "reasoning");    // 根据object对象名获得里面的badminton数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("reasoning = %s\n", v_str);}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "interest");if (item != NULL) {cJSON* obj = item->child;    // 获得 "basketball":    "篮球"while (obj) {if (obj->type == cJSON_String) {char* v_str = obj->valuestring;printf("%s = %s\n", obj->string, v_str);    // 可以通过string获得键}// 获取下一个元素obj = obj->next;}}}printf("*******************************6**************************************\n");//6.解析:"final":    ["BE", "HE"],{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "final");if (item != NULL) {int size = cJSON_GetArraySize(item);    // 获得数组个数for (int i = 0; i < size; i++) {cJSON* arr = cJSON_GetArrayItem(item, i);    // 根据索引获得数组中的值if (arr != NULL && arr->type == cJSON_String) {v_str = arr->valuestring;printf("final = %s\n", v_str);}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "final");if (item != NULL) {cJSON* arr = item->child;    // 获得 "black"while (arr) {if (arr->type == cJSON_String) {char* v_str = arr->valuestring;printf("final = %s\n", v_str);}// 获取下一个元素arr = arr->next;}}}printf("*******************************7**************************************\n");//7.解析:"like":    [{"game":    "斩赤红之瞳","Episodes" : 22}, {"game":    "文豪野犬","Episodes" : 84}],{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {int size = cJSON_GetArraySize(item);    // 获取的数组大小for (int i = 0; i < size; i++) {cJSON* obj = cJSON_GetArrayItem(item, i);        // 获取的数组里的objcJSON* val = NULL;if (obj != NULL && obj->type == cJSON_Object) {    // 判断数字内的元素是不是obj类型val = cJSON_GetObjectItem(obj, "game");        // 获得obj里的值if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("game = %s\n", v_str);}val = cJSON_GetObjectItem(obj, "Episodes");if (val != NULL && val->type == cJSON_Number) {v_double = val->valuedouble;printf("Episodes = %.2f\n", v_double);}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON* obj = item->child;while (obj) {if (obj->type == cJSON_Object) {cJSON* objValue = obj->child;while (objValue) {// 再通过类型去区分if (objValue->type == cJSON_String) {char* v_str = objValue->valuestring;printf("%s = %s\n", objValue->string, v_str);}else if (objValue->type == cJSON_Number) {double v_double = objValue->valuedouble;printf("%s = %.2f\n", objValue->string, v_double);}// 获取下一个元素objValue = objValue->next;}}// 获取下一组元素obj = obj->next;}}}printf("*******************************8**************************************\n");//8.解析:"education":    [["战斗", "热血"], ["推理", "格斗"]],{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {int size = cJSON_GetArraySize(item);    // 获取的数组大小for (int i = 0; i < size; i++) {cJSON* arr = cJSON_GetArrayItem(item, i);if (arr != NULL && arr->type == cJSON_Array) {int arrSize = cJSON_GetArraySize(arr);for (int j = 0; j < arrSize; j++) {cJSON* arr2 = cJSON_GetArrayItem(arr, j);    // 再进一步解析就可以得到数组里面的元素了if (arr2 != NULL && arr2->type == cJSON_String) {v_str = arr2->valuestring;printf("education = %s\n", v_str);}}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON* arr = item->child;while (arr) {if (arr->type == cJSON_Array) {cJSON* arrValue = arr->child;while (arrValue) {if (arrValue->type == cJSON_String) {char* v_str = arrValue->valuestring;printf("education = %s\n", v_str);}arrValue = arrValue->next;    // 获取下一个元素}}// 获取下一组arr = arr->next;}}}printf("*******************************9**************************************\n");//9.解析:"languages":    {"serialOne":    {"language":    "汉语","grade" : 10},"serialTwo" : {"language":    "英语","grade" : 6}},{/*************** 方式一 ***************/const char* arrStr[] = { "serialOne", "serialTwo" };        // 可以提前定义需要解析的对象键,这样就可以使用for循环进行解析了item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {cJSON* val = NULL;int size = sizeof(arrStr) / sizeof(char*);// 通过遍历指针数组,获得每个对象的键,在进行解析操作(如果不使用for循环解析,那就老老实实的写代码将全部个数解析完毕)for (int i = 0; i < size; i++) {cJSON* obj1 = cJSON_GetObjectItem(item, arrStr[i]);if (obj1 != NULL && obj1->type == cJSON_Object) {val = cJSON_GetObjectItem(obj1, "language");if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("education = %s\n", v_str);}val = cJSON_GetObjectItem(obj1, "grade");if (val != NULL && val->type == cJSON_Number) {v_int = val->valueint;printf("grade = %d\n", v_int);}}}}/*************** 方式二 ***************/// 在不知道键是什么的情况下 和 不知道有多少元素的情况下可用item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {// 获取到languages里的第一个子元素cJSON* obj = item->child;    // 也就是:"serialOne": { "language": "汉语", "grade": 10 }while (obj) {if (obj->type == cJSON_Object) {// 获取到子元素的子元素cJSON* value = obj->child;    // 也就是:{ "language": "汉语", "grade": 10 }while (value) {if (value->type == cJSON_String) {printf("%s = %s\n", value->string, value->valuestring);}else if (value->type == cJSON_Number) {printf("%s = %d\n", value->string, value->valueint);}// 通过next可以自由获取里面的元素了value = value->next;}}// 获得下一组子元素obj = obj->next;}}}fclose(file);}

5.删除


#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>#include <sys/stat.h>    // 获取文件大小#include "cJSON.h"
void main() {FILE* file = NULL;const char* FILE_NAME = "E:\\abs\\test.json";file = fopen(FILE_NAME, "r");if (file == NULL) {printf("Open file fail!\n");return;}// 获得文件大小struct stat statbuf;stat(FILE_NAME, &statbuf);int fileSize = statbuf.st_size;printf("文件大小:%d\n", fileSize);// 分配符合文件大小的内存char* jsonStr = (char*)malloc(sizeof(char) * fileSize + 1);memset(jsonStr, 0, fileSize + 1);// 读取文件中的json字符串int size = fread(jsonStr, sizeof(char), fileSize, file);if (size == 0) {printf("读取文件失败!\n");fclose(file);return;}printf("%s\n", jsonStr);fclose(file);// 将读取到的json字符串转换成json变量指针cJSON* root = cJSON_Parse(jsonStr);if (!root) {printf("Error before: [%s]\n", cJSON_GetErrorPtr());free(jsonStr);return;}free(jsonStr);cJSON* item = NULL;/* "name":    "blue"        ====>    "name":    "蓝色" */// 使用cJSON_ReplaceItemInObject可以直接进行修改cJSON_ReplaceItemInObject(root, "name", cJSON_CreateString("蓝色"));// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "name");if (item != NULL) {// 判断是不是字符串类型if (item->type == cJSON_String) {char* v_str = item->valuestring;        // 此赋值是浅拷贝,不需要现在释放内存printf("name = %s\n", v_str);}}/* "age": 20        ====>    "age": 25 */cJSON_ReplaceItemInObject(root, "age", cJSON_CreateNumber(25));// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "age");if (item != NULL) {// 判断是不是字符串类型if (item->type == cJSON_Number) {int v_int = item->valueint;printf("age = %d\n", v_int);}}/* "vip": true     ====>  "vip": false */// 使用cJSON_ReplaceItemInObject可以直接进行修改cJSON_ReplaceItemInObject(root, "vip", cJSON_CreateBool(false));// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "vip");if (item != NULL) {// 判断是不是字符串类型if (item->type == cJSON_False || item->type == cJSON_True) {char* v_str = cJSON_Print(item);        // 由于bool类型结构体中没有给出,所以使用字符串代替printf("vip = %s\n", v_str);free(v_str);v_str = NULL;}}/*"interest":    {                         修改后:     "interest":    {"combat":    "热血",            ====>                "combat":    "推理","reasoning":    "推理"                            "reasoning":    "热血"}                                                  }*/// 首先获取到需要修改的指针item = cJSON_GetObjectItem(root, "interest");if (item != NULL) {// 使用cJSON_ReplaceItemInObject可以直接进行修改cJSON_ReplaceItemInObject(item, "combat", cJSON_CreateString("推理"));cJSON_ReplaceItemInObject(item, "reasoning", cJSON_CreateString("热血"));}// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "interest");if (item != NULL) {cJSON* obj = item->child;while (obj) {if (obj->type == cJSON_String) {char* v_str = obj->valuestring;printf("%s = %s\n", obj->string, v_str);    // 可以通过string获得键}// 获取下一个元素obj = obj->next;}}/* "final":    ["BE", "HE"]        ====>        "color":["BEE", "HEE"]    */item = cJSON_GetObjectItem(root, "final");if (item != NULL) {cJSON_ReplaceItemInArray(item, 0, cJSON_CreateString("BEE"));cJSON_ReplaceItemInArray(item, 1, cJSON_CreateString("HEE"));}// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "final");if (item != NULL) {cJSON* arr = item->child;while (arr) {if (arr->type == cJSON_String) {char* v_str = arr->valuestring;printf("final = %s\n", v_str);}// 获取下一个元素arr = arr->next;}}/*"like": [                                     修改后:  "like": [{ "game": "斩赤红之瞳", "Episodes": 24 },      ====>               {  "game": "钢之炼金术士FA", "Episodes": 64 },{ "game": "文豪野犬", "Episodes": 84 }                        { "game": "夏日重现", "Episodes": 25 }],                                                       ],*/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON* arrObj = NULL;arrObj = cJSON_GetArrayItem(item, 0);    // 根据索引获得数组中的值cJSON_ReplaceItemInObject(arrObj, "game", cJSON_CreateString("钢之炼金术士FA"));cJSON_ReplaceItemInObject(arrObj, "Episodes", cJSON_CreateNumber(64));arrObj = cJSON_GetArrayItem(item, 1);    // 根据索引获得数组中的值cJSON_ReplaceItemInObject(arrObj, "game", cJSON_CreateString("夏日重现"));cJSON_ReplaceItemInObject(arrObj, "Episodes", cJSON_CreateNumber(25));}// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON* obj = item->child;while (obj) {if (obj->type == cJSON_Object) {cJSON* objValue = obj->child;while (objValue) {// 再通过类型去区分if (objValue->type == cJSON_String) {char* v_str = objValue->valuestring;printf("%s = %s\n", objValue->string, v_str);}else if (objValue->type == cJSON_Number) {double v_double = objValue->valuedouble;printf("%s = %.2f\n", objValue->string, v_double);}// 获取下一个元素objValue = objValue->next;}}// 获取下一组元素obj = obj->next;}}/*"education": [                修改后:    "education": [[ "小学", "初中" ],        ====>            [ "小学六年级", "初中初三" ],[ "高中", "大学" ]                        [ "高中高三", "大学大四" ]],                                        ],*/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON* arrArr = NULL;arrArr = cJSON_GetArrayItem(item, 0);    // 根据索引获得数组中的值cJSON_ReplaceItemInArray(arrArr, 0, cJSON_CreateString("小学六年级"));cJSON_ReplaceItemInArray(arrArr, 1, cJSON_CreateString("初中初三"));arrArr = cJSON_GetArrayItem(item, 1);    // 根据索引获得数组中的值cJSON_ReplaceItemInArray(arrArr, 0, cJSON_CreateString("高中高三"));cJSON_ReplaceItemInArray(arrArr, 1, cJSON_CreateString("大学大四"));}// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON* arr = item->child;    // 获得 [ "小学", "初中" ]while (arr) {if (arr->type == cJSON_Array) {cJSON* arrValue = arr->child;    // 获得 "小学"while (arrValue) {if (arrValue->type == cJSON_String) {char* v_str = arrValue->valuestring;printf("education = %s\n", v_str);}arrValue = arrValue->next;    // 获取下一个元素}}// 获取下一组arr = arr->next;}}/*"languages": {                                              修改后:       "languages": {"serialOne": { "language": "汉语", "grade": 10 },       ====>               "serialOne": { "language": "粤语", "grade": 9 },"serialTwo": { "language": "英语", "grade": 6}                            "serialTwo": { "language": "白话", "grade": 8 }},                                                                       },*/item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {cJSON* obj = NULL;obj = cJSON_GetObjectItem(item, "serialOne");// 使用cJSON_ReplaceItemInObject可以直接进行修改cJSON_ReplaceItemInObject(obj, "language", cJSON_CreateString("粤语"));cJSON_ReplaceItemInObject(obj, "grade", cJSON_CreateNumber(9));obj = cJSON_GetObjectItem(item, "serialTwo");// 使用cJSON_ReplaceItemInObject可以直接进行修改cJSON_ReplaceItemInObject(obj, "language", cJSON_CreateString("白话"));cJSON_ReplaceItemInObject(obj, "grade", cJSON_CreateNumber(8));}// 解析打印查看是否修改成功item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {// 获取到languages里的第一个子元素cJSON* obj = item->child;    // 也就是:"serialOne": { "language": "汉语", "grade": 10 }while (obj) {if (obj->type == cJSON_Object) {// 获取到子元素的子元素cJSON* value = obj->child;    // 也就是:{ "language": "汉语", "grade": 10 }while (value) {if (value->type == cJSON_String) {printf("%s = %s\n", value->string, value->valuestring);}else if (value->type == cJSON_Number) {printf("%s = %d\n", value->string, value->valueint);}// 通过next可以自由获取里面的元素了value = value->next;}}obj = obj->next;}}// 打开文件file = fopen(FILE_NAME, "w");if (file == NULL) {printf("Open file fail!\n");// 释放指针内存cJSON_Delete(root);return;}char* cjValue = cJSON_Print(root);// 写入文件int ret = fwrite(cjValue, sizeof(char), strlen(cjValue), file);if (ret == 0) {printf("写入文件失败!\n");}fclose(file);free(cjValue);// 使用了cJSON_Parse之后,记得调用cJSON_Delete函数释放cJSON_Delete(root);
}

6.修改

#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>#include <sys/stat.h>    // 获取文件大小#include "cJSON.h"void main() {FILE* file = NULL;const char* FILE_NAME = "E:\\abs\\test.json";file = fopen(FILE_NAME, "r");if (file == NULL) {printf("Open file fail!\n");return;}// 获得文件大小struct stat statbuf;stat(FILE_NAME, &statbuf);int fileSize = statbuf.st_size;printf("文件大小:%d\n", fileSize);// 分配符合文件大小的内存char* jsonStr = (char*)malloc(sizeof(char) * fileSize + 1);memset(jsonStr, 0, fileSize + 1);// 读取文件中的json字符串int size = fread(jsonStr, sizeof(char), fileSize, file);if (size == 0) {printf("读取文件失败!\n");fclose(file);return;}printf("%s\n", jsonStr);fclose(file);// 将读取到的json字符串转换成json变量指针cJSON* root = cJSON_Parse(jsonStr);if (!root) {printf("Error before: [%s]\n", cJSON_GetErrorPtr());free(jsonStr);return;}free(jsonStr);cJSON* item = NULL;// 使用这个函数直接进行删除cJSON_DeleteItemFromObject(root, "name");    // 通过键进行删除/* 删除:"interest":    {"combat":    "推理"}*/item = cJSON_GetObjectItem(root, "interest");// 获取到对应的节点对象就可以直接删除了if (item != NULL) {cJSON_DeleteItemFromObject(item, "combat");}/* final: "final":    ["HEE"] */item = cJSON_GetObjectItem(root, "final");// 获取到对应的节点数组就可以直接删除了if (item != NULL) {cJSON_DeleteItemFromArray(item, 1);    // 通过索引进行删除}/* 删除:"like":    [{ "game":    "夏日重现", "Episodes":    25 },]*/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON_DeleteItemFromArray(item, 0);//还可以再继续深入进行删除//cJSON *arrObj = cJSON_GetArrayItem(item, 0);    // 根据索引获得数组中的值//if (arrObj != NULL) {//    cJSON_DeleteItemFromObject(arrObj, "Episodes");//}}/* 删除: "education":    [["高中高三", "大学大四"]] */item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON_DeleteItemFromArray(item, 1);//还可以再继续深入进行删除//cJSON *arrArr = cJSON_GetArrayItem(item, 0);    // 根据索引获得数组中的值//if (arrArr != NULL) {//    cJSON_DeleteItemFromArray(arrArr, 1);//}}/* 删除"languages":    {"serialTwo":    { "language":"白话", "grade":8 }}*/item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {cJSON_DeleteItemFromObject(item, "serialTwo");//还可以再继续深入进行删除//cJSON *obj = cJSON_GetObjectItem(item, "serialOne");//if (obj != NULL) {//    cJSON_DeleteItemFromObject(obj, "grade");//}}// 打开文件file = fopen(FILE_NAME, "w");if (file == NULL) {printf("Open file fail!\n");// 释放指针内存cJSON_Delete(root);return;}char* cjValue = cJSON_Print(root);// 写入文件int ret = fwrite(cjValue, sizeof(char), strlen(cjValue), file);if (ret == 0) {printf("写入文件失败!\n");}fclose(file);free(cjValue);// 使用了cJSON_Parse之后,记得调用cJSON_Delete函数释放cJSON_Delete(root);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142155.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13.利用辗转相除法求两个整数的最大公约数和最小公倍数。如96,36

文章目录 前言一、题目描述 二、题目分析 三、解题 前言 本系列为循环结构编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 利用辗转相除法求两个整数的最大公约数和最小公倍数,如96,36 二、题目分析 最小公倍数(输入的两个数之积)除(它们的最大公约数) 三…

C++——友元函数

如下是一个日期类&#xff1a; class Date { public:Date(int year 2023, int month 10, int day 1){_year year;_month month;_day day;if (_month < 1 || month > 12 || _day < 1 || _day > GetMonthDay(_year, _month)){cout << "日期不规范&…

一篇博客读懂单链表——Single-List

目录 一、初识单链表 单链表是如何构造的&#xff1a; 单链表如何解决顺序表中的问题&#xff1a; 二、单链表的初始定义 三、尾插和头插 3.1 新建结点CreateNode 3.2 打印SLTPrint 3.3 尾插SLTPushBack 3.4 头插SLTPushFront 四、尾删和头删 4.1 尾删SLTPopBack…

hub.docker访问不了的问题(一步解决)

暂时我也不清楚&#xff0c;但是下面这个网址可以用(可以先用着)Docker Hub Container Image Library | App Containerization (axlinux.top)https://hub.axlinux.top/

Maya 2024 for Mac(3D建模软件)

Maya 2024是一款三维计算机图形软件&#xff0c;具有强大的建模、动画、渲染、特效等功能&#xff0c;广泛应用于影视、游戏、广告等行业。以下是Maya 2024软件的主要功能介绍&#xff1a; 建模&#xff1a;Maya 2024具有强大的建模工具&#xff0c;包括多边形建模、曲面建模、…

【工程实践】Docker使用记录

前言 服务上线经常需要将服务搬到指定的服务器上&#xff0c;经常需要用到docker&#xff0c;记录工作中使用过dcoker指令。 1.写Dockerfile 1.1 全新镜像 FROM nvidia/cuda:11.7.1-devel-ubuntu22.04ENV WORKDIR/data/Qwen-14B-Chat WORKDIR $WORKDIR ADD . $WORKDIR/RUN ap…

洗地机是智商税吗?洗地机有没有必要买?2023洗地机推荐

传统的扫地拖地方式不仅时间长&#xff0c;被毛孩子和萌娃制造的顽固污渍更是让人头痛不已&#xff0c;高效又有效的地面清洁方式成了我们最大的诉求。目前洗地机受到青睐&#xff0c;异常火爆&#xff0c;也成为一众清洁扫地的选择之一&#xff0c;那洗地机到底是不是智商税呢…

C语言从入门到精通之【printf和scanf函数】

printf()是输出函数&#xff0c;scanf()是输入函数&#xff0c;但是它们的工作原理几乎相同。两个函数都使用格式字符串和参数列表。 printf()函数的格式 printf( 格式字符串, 待打印项1, 待打印项2,…);待打印项1、待打印项2等都是要打印的项。它们可以是变量、常量&#xff…

业务出海之服务器探秘

这几年随着国内互联网市场的逐渐饱和&#xff0c;越来越多的公司加入到出海的行列&#xff0c;很多领域都取得了很不错的成就。虽然出海可以获得更加广阔的市场&#xff0c;但也需要面对很多之前在国内可能没有重视的一些问题。集中在海外服务器的选择维度上就有很大的变化。例…

使用validator实现枚举类型校验

使用validator实现枚举类型校验 前言&#xff1a; 在前端调用后端接口传递参数的过程中&#xff0c;我们往往需要对前端传递过来的参数进行校验&#xff0c;比如说我们此时需要对用户的状态进行更新&#xff0c;而用户的状态只有正常和已删除&#xff0c;并且是在代码中通过枚…

【华为云IaaS基础三件套之----计算ECS、网络EIP、存储EVS】

MD[华为云IaaS基础三件套----计算、网络、存储] 华为云IaaS基础三件套之----计算ECS、网络EIP、存储EVS 说明: 这里只是简单从计算/网络/存储&#xff0c;进行介绍&#xff0c;阐明云上对于云下的优势&#xff1b;因ECS是三者综合&#xff0c;故最后说明。 1.网络----弹性公…

Day02_《MySQL索引与性能优化》

文章目录 一、SQL执行顺序二、索引简介1、关于索引2、索引的类型Btree 索引Btree 索引 三、Explain简介四、Explain 详解1、id2、select_type3、table4、type5、possible_keys6、key7、key_len8、ref9、rows10、Extra11、小案例 五、索引优化1、单表索引优化2、两表索引优化3、…

安装 Lua 的 HTTP 库

首先&#xff0c;你需要安装 Lua 的 HTTP 库。可以使用 LuaRocks 来安装。以下是安装命令&#xff1a; luarocks install http然后&#xff0c;你可以使用以下代码来爬取网页内容&#xff1a; local http require http-- 设置代理信息 http.set_proxy(jshk.com.cn)-- 网页UR…

灵活运用Vue指令:探究v-if和v-for的使用技巧和注意事项

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、作…

为什么打开idea时,没有启动页面,如何解决?

更新idea2021.2后&#xff0c;当双击idea打开时&#xff0c;发现没有启动界面&#xff0c;直接进入IDEA界面&#xff0c;中间等待时间&#xff0c;让人误以为没有打开idea成功&#xff0c;使得多次点击idea图标。 解决方案就是 在idea界面菜单栏中找到帮助&#xff08;Help)&a…

全域全自主建设,亚信科技AntDB数据库助力广电5G业务上线运行

自2019年6月&#xff0c;中国广电成功获得5G牌照以来&#xff0c;迅速推进网络建设目标&#xff0c;成为5G网络覆盖广、应用场景多、用户体验出色的第四大运营商。其依托全球独有的700MHz频谱资源&#xff0c;具备覆盖能力强、容量足、速率高的优势。通过不断深化和中国移动的共…

Gempy 实现地理位置3D模型的展示以及导出

1. 首先安装python gempy 包 pip install gempy python 版本 3.10 这个很重要,版本不同可能会报错 2. gdal 可能会报错, 一下地址根据python版本下载,然后移入到python解释器环境中, Script文件中,然后cmd ,pip install 文件名安装即可 Releases cgohlke/geospatial-wheels …

μC/OS-II---计时器管理2(os_tmr.c)

目录 获取计时器的名字获取计时器到期前剩余的时间查看计时器的状态 计时器是倒计时器&#xff0c;当计数器达到零时执行某个动作。用户通过回调函数提供这个动作。回调函数是用户声明的函数&#xff0c;在计时器到期时被调用。在回调函数中绝对不能进行阻塞调用&#xff08;例…

《008.SpringBoot之教务系统》【界面简洁功能简单】

《008.SpringBoot之教务系统》【界面简洁功能简单】 项目简介 [1]本系统涉及到的技术主要如下&#xff1a; 推荐环境配置&#xff1a;DEA jdk1.8 Maven MySQL 前后端分离; 后台&#xff1a;SpringBootMybatis; 前台&#xff1a;JSPBootStrap; [2]功能模块展示&#xff1a; 管…

[文件读取]coldfusion 文件读取 (CVE-2010-2861)

1.1漏洞描述 漏洞编号CVE-2010-2861漏洞类型文件读取漏洞等级⭐⭐漏洞环境VULFOCUS攻击方式 描述: Adobe ColdFusion是美国Adobe公司的一款动态Web服务器产品&#xff0c;其运行的CFML&#xff08;ColdFusion Markup Language&#xff09;是针对Web应用的一种程序设计语言。 A…