cJSON库的使用详情
什么是JSON?
JSON(JavaScript Object Notation)是一个用于数据交换的文本格式,现时的标准为ECMA-404。
JSON 是轻量级的文本数据交换格式,几乎所有与网页开发相关的语言都有JSON库。
JSON比XML更小、更快,JSON是一种开放的、轻量级的数据交换格式,采用独立于编程语言的文本格式来存储和表示数据,易于程序员阅读与编写,同时也易于计算机解析和生成,通常用于在 Web 客户端(浏览器)与 Web 服务器端之间传递数据。
例如,一个动态网页想从服务器获得数据时,服务器从数据库查找数据,然后把数据转换成 JSON 文本格式:
{
"title": "Design Patterns",
"subtitle": "Elements of Reusable Object-Oriented Software",
"author": [
"Erich Gamma",
"Richard Helm",
"Ralph Johnson",
"John Vlissides"
],
"year": 2009,
"weight": 1.8,
"hardcover": true,
"publisher": {
"Company": "Pearson Education",
"Country": "India"
},
"website": null
}
从此例子可看出,JSON 是树状结构,而 JSON 只包含 6 种数据类型:
- null: 表示为 null
- boolean: 表示为 true 或 false
- number: 一般的浮点数表示方式
- string: 表示为 “…”
- array: 表示为 [ … ]
- object: 表示为 { … }
实现的 JSON 库,主要是完成 3 个需求:
- 把 JSON 文本解析为一个树状数据结构(parse)。
- 提供接口访问该数据结构(access)。
- 把数据结构转换成 JSON 文本(stringify)。
一、cJSON动态库制作:
1.下载cJSON开源库:cJSON库
2.把这两个文件放到目录中
3.制作动态库cjson
gcc -shared -fPIC cJSON.c -o libcjson.so
-shared :表示生成的是.so动态库文件
-fPIC:表示代码和地址无关,不需要被不同模块重定位,生成PIC代码。为了达到动态链接的目的。
sudo cp libcjson.so /lib
- 运行程序时需要将库文件拷贝到 /usr/lib 或者/lib 中才能运行.
- 或者把库所在的路径添加到/etc/ld.so.conf, 执行ldconfig /etc/ld_so.conf
4.编译运行
gcc xx.c -lcjson -lm
./a.out
二、cJSON介绍
1.json数据表示方式
在json中使用两种方式表示数据
-
Object(对象):键/值对的集合,使用**{ }**定义。在以键开头,后跟冒号:最后是值,多个键/值之间用 **,**逗号分隔
-
Array(数组):值的有序集合,使用 []定义,数组中每个值之间用逗号**,**分隔
2.cJSON的结构体
/* 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; /* 当前json对象的类型 */
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; /* 键 */
} cJSON;
3.cJSON宏定义的类型type
/* cJSON Types: */
#define cJSON_False 0 //false
#define cJSON_True 1 //true
#define cJSON_NULL 2 //NULL
#define cJSON_Number 3 //数字
#define cJSON_String 4 //字符串
#define cJSON_Array 5 //数组
#define cJSON_Object 6 //对象
4.字符串生成的cJSON指针的函数,使用后需要调用cJSON_Delete进行释放
extern cJSON *cJSON_Parse(const char *value);
// 释放cJSON_Parse返回的指针
extern void cJSON_Delete(cJSON *c);
5.cjson指针指针生成字符串的函数
// 这个生成的字符串有做格式调整
extern char *cJSON_Print(cJSON *item);
// 这个没有作格式调整,就是一行字符串显示
extern char *cJSON_PrintUnformatted(cJSON *item);
// Free the char* when finished.否则会造成内存泄漏
三、封装JSON数据
1.定义对象{},添加键值对 :{“name”:“client”}
main.c
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file=NULL;
file = fopen(JSON_PATH,"w+");
if(file == NULL)
{
perror("fopen");
return ;
}
cJSON *root;
//定义对象{ }
root = cJSON_CreateObject();
//插入元素 键值对"name":"client"
cJSON_AddItemToObject(root,"name",cJSON_CreateString("client"));
char *s = cJSON_Print(root);
printf("%s\n",s);
fwrite(s,sizeof(char),strlen(s),file);
free(s);
fclose(file);
cJSON_Delete(root);
return ;
}
//gcc main.c -lcjson -lm
效果如下:
2.定义数组[],添加值:[“red”,“green”,“blue”]
cJSON *colorArray;
colorArray = cJSON_CreateArray(); //[]
cJSON_AddItemToArray(colorArray,cJSON_CreateString("red"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("green"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("blue"));
//colorArray ["red","green","blue"]
cJSON_AddItemToObject(root,"color",colorArray);
效果如下:
3.数组嵌套[[],[]]:[[“xx”,“xx”],[“xx”,“xx”]]
//[[""],[""]]
cJSON *languageArray,*usaArr,*ukArr;
languageArray = cJSON_CreateArray();
usaArr = cJSON_CreateArray();
ukArr = cJSON_CreateArray();
cJSON_AddItemToArray(usaArr,cJSON_CreateString("USA"));
cJSON_AddItemToArray(usaArr,cJSON_CreateString("American English"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("UK"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("British English"));
//usaArr ["USA","American English"]
//ukArr ["UK","British English"]
cJSON_AddItemToArray(languageArray,usaArr);
cJSON_AddItemToArray(languageArray,ukArr);
//languageArray [["USA", "American English"], ["UK", "British English"]]
cJSON_AddItemToObject(root,"Languages",languageArray);
效果如下:
4.对象嵌套对象{{},{}}:{“xx”:{“xx”:“xx”},“xx”:{“xx”:“xx”}}:
“address”:{“南方”:{“city”:“四川成都”,“street”:“建设路”},“北方”:{“city”:“北京”,“street”:“长安街”}}
cJSON *address,*cdCity,*bjCity;
address = cJSON_CreateObject();
cdCity = cJSON_CreateObject();
bjCity = cJSON_CreateObject();
cJSON_AddItemToObject(cdCity,"street",cJSON_CreateString("成华大道"));
cJSON_AddItemToObject(cdCity,"city",cJSON_CreateString("四川成都"));
//cdCity {"city":"四川成都","street":"建设路"}
cJSON_AddItemToObject(bjCity,"street",cJSON_CreateString("长安街"));
cJSON_AddItemToObject(bjCity,"city",cJSON_CreateString("北京"));
//cjCity {"city":"北京","street":"长安街"}
cJSON_AddItemToObject(address,"南方",cdCity);
cJSON_AddItemToObject(address,"北方",bjCity);
//address {"南方":{"city":"四川成都","street":"建设路"},"北方":{"city":"北京","street":"长安街"}}
cJSON_AddItemToObject(root,"address",address);
效果如下:
5.对象嵌套数组对象{ [{},{}] }:{“xx”:[{“xx”:“xx”},{“xx”:“xx”}]}
{“links”:[{“name”:“Google”,“url”:“http://www.google.com”},{“name”:“Baidu”,“url”:“http://www.baidu.com”}]}
cJSON *linkArry,*obj1,*obj2;
linkArry = cJSON_CreateArray(); //[]定义数组
obj1 = cJSON_CreateObject(); //{}
cJSON_AddItemToObject(obj1,"name",cJSON_CreateString("Google"));
cJSON_AddItemToObject(obj1,"url",cJSON_CreateString("http://www.google.com"));
//obj1 {"name":"Google","url":"http://www.google.com"}
obj2 = cJSON_CreateObject();
cJSON_AddItemToObject(obj2,"name",cJSON_CreateString("Baidu"));
cJSON_AddItemToObject(obj2,"url",cJSON_CreateString("http://www.baidu.com"));
//obj2 {"name":"Baidu","url":"http://www.baidu.com"}
cJSON_AddItemToArray(linkArry,obj1);
cJSON_AddItemToArray(linkArry,obj2);
//linkArry [{"name":"Google","url":"http://www.google.com"},{"name":"Baidu","url":"http://www.baidu.com"}]
cJSON_AddItemToObject(root,"links",linkArry);
效果如下:
完整代码:main.c
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file=NULL;
file = fopen(JSON_PATH,"w+");
if(file == NULL)
{
perror("fopen");
return ;
}
// /* These calls create a cJSON item of the appropriate type. */
// extern cJSON *cJSON_CreateNull(void);
// extern cJSON *cJSON_CreateTrue(void);
// extern cJSON *cJSON_CreateFalse(void);
// extern cJSON *cJSON_CreateBool(int b);
// extern cJSON *cJSON_CreateNumber(double num);
// extern cJSON *cJSON_CreateString(const char *string);
// extern cJSON *cJSON_CreateArray(void);
// extern cJSON *cJSON_CreateObject(void);
// /* These utilities create an Array of count items. */
// extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
// extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
cJSON *root;
//定义 键值对 {"name":"client"}
//{"":""}
root = cJSON_CreateObject();
cJSON_AddItemToObject(root,"name",cJSON_CreateString("client"));
cJSON_AddItemToObject(root,"cJSON_CreateNull",cJSON_CreateNull());
cJSON_AddItemToObject(root,"cJSON_CreateTrue",cJSON_CreateTrue());
cJSON_AddItemToObject(root,"cJSON_CreateFalse",cJSON_CreateFalse());
cJSON_AddItemToObject(root,"cJSON_CreateBool",cJSON_CreateBool(23));
cJSON_AddItemToObject(root,"cJSON_CreateBool0",cJSON_CreateBool(0));
cJSON_AddItemToObject(root,"cJSON_CreateNumber",cJSON_CreateNumber(9999999));
//["",""]
cJSON *colorArray;
colorArray = cJSON_CreateArray(); //[]
cJSON_AddItemToArray(colorArray,cJSON_CreateString("red"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("green"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("blue"));
cJSON_AddItemToObject(root,"color",colorArray);
//[[""],[""]]
cJSON *languageArray,*usaArr,*ukArr;
languageArray = cJSON_CreateArray();
usaArr = cJSON_CreateArray();
ukArr = cJSON_CreateArray();
cJSON_AddItemToArray(usaArr,cJSON_CreateString("USA"));
cJSON_AddItemToArray(usaArr,cJSON_CreateString("American English"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("UK"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("British English"));
cJSON_AddItemToArray(languageArray,usaArr);
cJSON_AddItemToArray(languageArray,ukArr);
cJSON_AddItemToObject(root,"Languages",languageArray);
// {"xx":{"xx":"xx"},"xx":{"xx":"xx"}}
cJSON *address,*cdCity,*bjCity;
address = cJSON_CreateObject();
cdCity = cJSON_CreateObject();
bjCity = cJSON_CreateObject();
cJSON_AddItemToObject(cdCity,"street",cJSON_CreateString("成华大道"));
cJSON_AddItemToObject(cdCity,"city",cJSON_CreateString("四川成都"));
cJSON_AddItemToObject(bjCity,"street",cJSON_CreateString("长安街"));
cJSON_AddItemToObject(bjCity,"city",cJSON_CreateString("北京"));
cJSON_AddItemToObject(address,"南方",cdCity);
cJSON_AddItemToObject(address,"北方",bjCity);
cJSON_AddItemToObject(root,"address",address);
//{[{},{}]}
cJSON *linkArry,*obj1,*obj2;
linkArry = cJSON_CreateArray(); //[]
obj1 = cJSON_CreateObject(); //{}
cJSON_AddItemToObject(obj1,"name",cJSON_CreateString("Google"));
cJSON_AddItemToObject(obj1,"url",cJSON_CreateString("http://www.google.com"));
obj2 = cJSON_CreateObject();
cJSON_AddItemToObject(obj2,"name",cJSON_CreateString("Baidu"));
cJSON_AddItemToObject(obj2,"url",cJSON_CreateString("http://www.baidu.com"));
cJSON_AddItemToArray(linkArry,obj1);
cJSON_AddItemToArray(linkArry,obj2);
cJSON_AddItemToObject(root,"links",linkArry);
char *s = cJSON_Print(root);
printf("%s\n",s);
fwrite(s,sizeof(char),strlen(s),file);
free(s);
fclose(file);
cJSON_Delete(root);
return ;
}
编译运行
gcc main.c -lcjson -lm
./a.out
效果如下:
四、解析JSON数据
1.读取.json文件
stat获取文件信息:Linux文件属性
c语言标准IO:C语言标准IO
先通过stat获取文件大小,动态分配内存空间jsonStr,再fread读取
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file = NULL;
int fileSize;
char *jsonStr;
struct stat statBuf; //文件属性结构体
file = fopen(JSON_PATH,"r");
if(file == NULL)
{
perror("fopen");
return;
}
stat(JSON_PATH, &statBuf);
fileSize = statBuf.st_size;
// printf("文件大小为:%d\n",fileSize);
// 分配内存
jsonStr = (char *)malloc(sizeof(char) * fileSize + 1);
bzero(jsonStr,fileSize + 1);
if(fread(jsonStr,fileSize,1,file) == 0)
printf("文件读取失败");
printf("%s\n",jsonStr);
free(jsonStr);
fclose(file);
return ;
}
2.通过cJSON_Parse函数解析jsonStr字符串
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
将读取到的jsonStr字符串转为json数据,用cJSON结构体指针接收
// 将读取到的json字符串转换成json变量指针
cJSON *root = cJSON_Parse(jsonStr);
if (!root) {
const char *err = cJSON_GetErrorPtr();
printf("Error before: [%s]", err);
free((void *)err);
free(jsonStr);
return;
}
char *s = cJSON_Print(root);
printf("%s\n",s);
free(s);
free(jsonStr);
3.直接进行解析
//cJSON结构体中的数据
// 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 *j_str = NULL;
double j_double = 0.0;
int j_int = 0;
bool j_bool = false;
//解析:"name":"client"
item = cJSON_GetObjectItem(root,"name");
if(item != NULL)
{
//判断是不是字符串
if(item->type == cJSON_String)
{
//获取字符串中的值
j_str = item->valuestring; //浅拷贝 j_str与item->valuestring指向的空间相同
printf("%s\n",j_str);
j_str[0] = 'y';
printf("%s\n",j_str); //ylient
printf("%s\n",item->valuestring); //ylient
j_str = malloc(strlen(item->valuestring) + 1);
strcpy(j_str,item->valuestring); //深拷贝
j_str[0] = 'c';
printf("%s\n",j_str); //client
printf("%s\n",item->valuestring); //ylient
free(j_str);
}
}
// 类型判断
/* 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_CreateNumber": 9999999
item = cJSON_GetObjectItem(root,"cJSON_CreateNumber");
if(item != NULL)
{
//判断是不是数字
if(item->type == cJSON_Number)
{
j_int = item->valueint;
printf("%d\n",j_int); //9999999
}
}
// "cJSON_CreateNull": null
item = cJSON_GetObjectItem(root,"cJSON_CreateNull");
if(item != NULL)
{
if(item->type == cJSON_NULL)
{
j_str = cJSON_Print(item); //深拷贝 Free the char* when finished.
printf("%s\n",j_str);
free(j_str);
}
}
// "cJSON_CreateTrue": true
item = cJSON_GetObjectItem(root,"cJSON_CreateTrue");
if(item != NULL)
{
if(item->type == cJSON_True)
{
j_str = cJSON_Print(item); //由于bool类型结构体中没有给出,所以使用字符串代替
printf("%s\n",j_str);
free(j_str);
}
}
// "cJSON_CreateBool0": false
item = cJSON_GetObjectItem(root,"cJSON_CreateBool0");
if(item != NULL)
{
if(item->type == cJSON_False)
{
j_str = cJSON_Print(item);
printf("%s\n",j_str);
free(j_str);
}
}
效果如下图:
4.解析数组
解析代码:
item = cJSON_GetObjectItem(root,"color");
if(item != NULL)
{
if (item->type == cJSON_Array)
{
int size = cJSON_GetArraySize(item); //获取数组中元素个数
for(int i=0;i<size;i++)
{
cJSON *obj = cJSON_GetArrayItem(item,i);
if(obj != NULL && obj->type == cJSON_String)
{
printf("color : %s\n",obj->valuestring);
}
}
}
}
5.解析{{},{}}
item = cJSON_GetObjectItem(root,"address");
if(item != NULL)
{
cJSON *val = NULL;
cJSON *south = cJSON_GetObjectItem(item,"南方");
cJSON *north = cJSON_GetObjectItem(item,"北方");
if(south != NULL)
{
val = cJSON_GetObjectItem(south,"city");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(south,"street");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
if(north != NULL)
{
val = cJSON_GetObjectItem(north,"city");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(north,"street");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
}
6.解析 [{ },{ }]
解析代码:
// "links": [{
// "name": "Google",
// "url": "http://www.google.com"
// }, {
// "name": "Baidu",
// "url": "http://www.baidu.com"
// }]
//方式一:
item = cJSON_GetObjectItem(root,"links"); //获取数组对象item [{},{}]
cJSON *obj;
if(item != NULL)
{
int size = cJSON_GetArraySize(item);
for(int i=0;i<size;i++)
{
obj = cJSON_GetArrayItem(item,i);
if(obj->type == cJSON_Object)
{
val = cJSON_GetObjectItem(obj,"name");
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(obj,"url");
printf("%s\n",val->valuestring);
}
}
}
printf("%d-----------------------------------\n",__LINE__);
//方式二:
item = cJSON_GetObjectItem(root,"links");
if (item != NULL)
{
obj = item->child; //{ "name": "Google", "url": "http://www.google.com" }
while(obj)
{
if(obj->type == cJSON_Object)
{
val = obj->child; //获取 "name": "Google"
while(val)
{
if(val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = val->next; //再获取 "url": "http://www.google.com"
}
}
// 获取下一组元素
obj = obj->next;
}
}
7.解析解析[[],[]]
代码如下:
printf("%d-----------------------------------\n",__LINE__);
//方式一:
// "Languages": [["USA", "American English"], ["UK", "British English"]]
cJSON *arr;
item =cJSON_GetObjectItem(root,"Languages"); //[[],[]]
if(item != NULL)
{
if(item->type == cJSON_Array)
{
int size1 = cJSON_GetArraySize(item);
for(int i=0;i<size1;i++)
{
arr = cJSON_GetArrayItem(item,i);
if(arr->type == cJSON_Array)
{
int size2 = cJSON_GetArraySize(arr);
for(int j=0;j<size2;j++)
{
val = cJSON_GetArrayItem(arr,j);
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
}
}
}
}
printf("%d-----------------------------------\n",__LINE__);
//方式二:
item = cJSON_GetObjectItem(root,"Languages");
if (item != NULL)
{
arr = item->child;
while(arr)
{
if (arr->type == cJSON_Array)
{
val = arr->child;
while(val)
{
if(val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = val->next;
}
}
arr = arr->next;
}
}
结果如下图
五、修改JSON数据
1.读取.json文件,打开文件读取字符串然后通过cJSON_Parse()转为JSON数据
需要用到的cJSON库函数:
/* Shifts pre-existing items to the right. */
/* Update array items. */
//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);
代码框架如下:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file = NULL;
int fileSize;
char *jsonStr,*s;
struct stat statBuf; //文件属性结构体
file = fopen(JSON_PATH,"r");
if(file == NULL)
{
perror("fopen");
return;
}
stat(JSON_PATH, &statBuf);
fileSize = statBuf.st_size;
// printf("文件大小为:%d\n",fileSize);
// 分配内存
jsonStr = (char *)malloc(sizeof(char) * fileSize + 1);
bzero(jsonStr,fileSize + 1);
if(fread(jsonStr,fileSize,1,file) == 0)
printf("文件读取失败");
cJSON *root = cJSON_Parse(jsonStr);
char *s = cJSON_Print(root);
printf("%s\n",s);
free(s);
free(jsonStr);
fclose(file);
cJSON_Delete(root);
}
2.直接修改 ,修改键值对中的值
cJSON *root = cJSON_Parse(jsonStr);
// "name": "client" ----> "name": "server"
// "cJSON_CreateTrue": true, ----> "cJSON_CreateTrue": false
// "cJSON_CreateFalse": false, ----> "cJSON_CreateFalse": true
// "cJSON_CreateBool": true, ----> "cJSON_CreateBool": false
// "cJSON_CreateBool0": false, ----> "cJSON_CreateBool0": true
// "cJSON_CreateNumber": 9999999 ----> "cJSON_CreateNumber": 66
cJSON_ReplaceItemInObject(root, "name", cJSON_CreateString("server"));
cJSON_ReplaceItemInObject(root,"cJSON_CreateNumber",cJSON_CreateNumber(66));
cJSON_ReplaceItemInObject(root,"cJSON_CreateTrue",cJSON_CreateFalse());
cJSON_ReplaceItemInObject(root,"cJSON_CreateFalse",cJSON_CreateTrue());
cJSON_ReplaceItemInObject(root,"cJSON_CreateBool",cJSON_CreateBool(0));
cJSON_ReplaceItemInObject(root,"cJSON_CreateBool0",cJSON_CreateBool(10));
3.修改[]中的值
// "color": ["red", "green", "blue"] ---> "color": ["yellow", "black", "white"]
cJSON *item;
item = cJSON_GetObjectItem(root,"color");
if(item != NULL)
{
cJSON_ReplaceItemInArray(item,0,cJSON_CreateString("yellow"));
cJSON_ReplaceItemInArray(item,1,cJSON_CreateString("black"));
cJSON_ReplaceItemInArray(item,2,cJSON_CreateString("white"));
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
4.修改 {{ },{ } } 中的值
/*
"address": {
"南方": {
"street": "成华大道", --->"street": "天府三街"
"city": "四川成都" --->"city": "Chengtu"
},
"北方": {
"street": "长安街", --->"street": "祈年大街"
"city": "北京" --->"city": "Peking"
}
}
*/
cJSON *north,*south;
item = cJSON_GetObjectItem(root,"address");
if(item != NULL)
{
south = cJSON_GetObjectItem(item,"南方");
if(south != NULL && south->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(south,"street",cJSON_CreateString("天府三街"));
cJSON_ReplaceItemInObject(south,"city",cJSON_CreateString("Chengtu"));
}
north = cJSON_GetObjectItem(item,"北方");
if(north != NULL && north->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(north,"street",cJSON_CreateString("祈年大街"));
cJSON_ReplaceItemInObject(north,"city",cJSON_CreateString("Peking"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
5.修改[ { },{ } ] 中的值
/*
"links": [{
"name": "Google", --->"name": "Bing"
"url": "http://www.google.com" --->"url": "https://cn.bing.com/"
}, {
"name": "Baidu", --->"name": "搜狗"
"url": "http://www.baidu.com" --->"url": "https://www.sogou.com/"
}]
*/
cJSON *obj;
item = cJSON_GetObjectItem(root,"links");
if(item != NULL)
{
obj = cJSON_GetArrayItem(item,0);
if(obj != NULL && obj->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(obj,"name",cJSON_CreateString("Bing"));
cJSON_ReplaceItemInObject(obj,"url",cJSON_CreateString("https://cn.bing.com/"));
}
obj = cJSON_GetArrayItem(item,1);
if(obj != NULL && obj->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(obj,"name",cJSON_CreateString("搜狗"));
cJSON_ReplaceItemInObject(obj,"url",cJSON_CreateString("https://www.sogou.com/"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
6.修改[ [ ],[ ] ]中的值
// "Languages": [["USA", "American English"], ["UK", "British English"]]
// --->"Languages": [["Fr", "French"], ["GER", "German"]]
cJSON *arr;
item = cJSON_GetObjectItem(root,"Languages");
if(item != NULL && item->type == cJSON_Array)
{
arr = cJSON_GetArrayItem(item,0);
if(arr != NULL && arr->type == cJSON_Array)
{
cJSON_ReplaceItemInArray(arr,0,cJSON_CreateString("Fr"));
cJSON_ReplaceItemInArray(arr,1,cJSON_CreateString("French"));
}
arr = cJSON_GetArrayItem(item,1);
if(arr != NULL && arr->type == cJSON_Array)
{
cJSON_ReplaceItemInArray(arr,0,cJSON_CreateString("GER"));
cJSON_ReplaceItemInArray(arr,1,cJSON_CreateString("German"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
六、删除json数据
需要用到的cJSON库函数:
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);//删除 并获取
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);//删除
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
1.直接删除 键值对
cJSON *root,*item;
root = cJSON_Parse(jsonStr);
/* 删除: "name": "client" */
// 使用这个函数直接进行删除
// cJSON_DeleteItemFromObject(root, "name"); // 通过键进行删除
cJSON *tmp = cJSON_DetachItemFromObject(root,"name"); //通过键获取"client" ,且从原root中去掉了"name": "client"
s = cJSON_Print(tmp);
printf("%s\n",s);
free(s);
2.删除 { } 中的值
/*
"address": {
"南方": {
"street": "成华大道",
"city": "四川成都"
},
"北方": {
"street": "长安街",
"city": "北京"
}
}
*/
// --->
/*
"南方": {
"street": "成华大道"
}
*/
//删除"南方"对象中的city 键值对
cJSON *south,*north;
item = cJSON_GetObjectItem(root,"address");
if(item != NULL && item->type == cJSON_Object)
{
south = cJSON_GetObjectItem(item,"南方");
cJSON_DeleteItemFromObject(south,"city");
s = cJSON_Print(south);
printf("%s\n",s);
free(s);
}
printf("%d-----------------------------------\n",__LINE__);
//直接删除"北方"对象
if(item != NULL && item->type == cJSON_Object)
{
cJSON_DeleteItemFromObject(item,"北方");
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
3.删除[]中的值
// "color": ["red", "green", "blue"]
// 删除 "red" "green"
item = cJSON_GetObjectItem(root,"color");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
if(item != NULL && item->type == cJSON_Array)
{
int size = cJSON_GetArraySize(item);
printf("%d\n",size);
cJSON_DeleteItemFromArray(item,0); //删除 "red"
cJSON_DeleteItemFromArray(item,0); //删除 "green"
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
4.删除[[],[]]中的值
// "Languages": [["USA", "American English"], ["UK", "British English"]]
//删除 ["USA", "American English"]
//删除 "British English"
cJSON *arr;
item = cJSON_GetObjectItem(root,"Languages");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
if(item != NULL && item->type == cJSON_Array)
{
//元素删除后 后面的元素下标改变
cJSON_DeleteItemFromArray(item,0); //删除 ["USA", "American English"]
arr = cJSON_GetArrayItem(item,0); //获取首元素 [ ["UK", "British English"] ]
cJSON_DeleteItemFromArray(arr,1); //删除 "British English"
s = cJSON_Print(arr);
printf("%s\n",s);
free(s);
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
5.删除[ { },{ } ]中的值
/*
"links": [{
"name": "Google",
"url": "http://www.google.com"
}, {
"name": "Baidu",
"url": "http://www.baidu.com"
}]
*/
//删除 { "name": "Google", "url": "http://www.google.com" }
//再删除 "name": "Baidu"
cJSON *obj;
item = cJSON_GetObjectItem(root,"links");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
if(item != NULL && item->type == cJSON_Array)
{
cJSON_DeleteItemFromArray(item,0); //删除{ "name": "Google", "url": "http://www.google.com" }
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
obj = cJSON_GetArrayItem(item,0);
cJSON_DeleteItemFromObject(obj,"name"); //删除 "name": "Baidu"
s = cJSON_Print(obj);
printf("%s\n",s);
free(s);
}
printf("%d-----------------------------------\n",__LINE__);
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
七、全部代码
1.封装
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file=NULL;
file = fopen(JSON_PATH,"w+");
if(file == NULL)
{
perror("fopen");
return ;
}
// /* These calls create a cJSON item of the appropriate type. */
// extern cJSON *cJSON_CreateNull(void);
// extern cJSON *cJSON_CreateTrue(void);
// extern cJSON *cJSON_CreateFalse(void);
// extern cJSON *cJSON_CreateBool(int b);
// extern cJSON *cJSON_CreateNumber(double num);
// extern cJSON *cJSON_CreateString(const char *string);
// extern cJSON *cJSON_CreateArray(void);
// extern cJSON *cJSON_CreateObject(void);
// /* These utilities create an Array of count items. */
// extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
// extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
cJSON *root;
//定义 键值对 {"name":"client"}
//{"":""}
root = cJSON_CreateObject();
cJSON_AddItemToObject(root,"name",cJSON_CreateString("client"));
cJSON_AddItemToObject(root,"cJSON_CreateNull",cJSON_CreateNull());
cJSON_AddItemToObject(root,"cJSON_CreateTrue",cJSON_CreateTrue());
cJSON_AddItemToObject(root,"cJSON_CreateFalse",cJSON_CreateFalse());
cJSON_AddItemToObject(root,"cJSON_CreateBool",cJSON_CreateBool(23));
cJSON_AddItemToObject(root,"cJSON_CreateBool0",cJSON_CreateBool(0));
cJSON_AddItemToObject(root,"cJSON_CreateNumber",cJSON_CreateNumber(9999999));
//["",""]
cJSON *colorArray;
colorArray = cJSON_CreateArray(); //[]
cJSON_AddItemToArray(colorArray,cJSON_CreateString("red"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("green"));
cJSON_AddItemToArray(colorArray,cJSON_CreateString("blue"));
cJSON_AddItemToObject(root,"color",colorArray);
//[[""],[""]]
cJSON *languageArray,*usaArr,*ukArr;
languageArray = cJSON_CreateArray();
usaArr = cJSON_CreateArray();
ukArr = cJSON_CreateArray();
cJSON_AddItemToArray(usaArr,cJSON_CreateString("USA"));
cJSON_AddItemToArray(usaArr,cJSON_CreateString("American English"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("UK"));
cJSON_AddItemToArray(ukArr,cJSON_CreateString("British English"));
cJSON_AddItemToArray(languageArray,usaArr);
cJSON_AddItemToArray(languageArray,ukArr);
cJSON_AddItemToObject(root,"Languages",languageArray);
// {"xx":{"xx":"xx"},"xx":{"xx":"xx"}}
cJSON *address,*cdCity,*bjCity;
address = cJSON_CreateObject();
cdCity = cJSON_CreateObject();
bjCity = cJSON_CreateObject();
cJSON_AddItemToObject(cdCity,"street",cJSON_CreateString("成华大道"));
cJSON_AddItemToObject(cdCity,"city",cJSON_CreateString("四川成都"));
cJSON_AddItemToObject(bjCity,"street",cJSON_CreateString("长安街"));
cJSON_AddItemToObject(bjCity,"city",cJSON_CreateString("北京"));
cJSON_AddItemToObject(address,"南方",cdCity);
cJSON_AddItemToObject(address,"北方",bjCity);
cJSON_AddItemToObject(root,"address",address);
//{[{},{}]}
cJSON *linkArry,*obj1,*obj2;
linkArry = cJSON_CreateArray(); //[]
obj1 = cJSON_CreateObject(); //{}
cJSON_AddItemToObject(obj1,"name",cJSON_CreateString("Google"));
cJSON_AddItemToObject(obj1,"url",cJSON_CreateString("http://www.google.com"));
obj2 = cJSON_CreateObject();
cJSON_AddItemToObject(obj2,"name",cJSON_CreateString("Baidu"));
cJSON_AddItemToObject(obj2,"url",cJSON_CreateString("http://www.baidu.com"));
cJSON_AddItemToArray(linkArry,obj1);
cJSON_AddItemToArray(linkArry,obj2);
cJSON_AddItemToObject(root,"links",linkArry);
char *s = cJSON_Print(root);
printf("%s\n",s);
fwrite(s,sizeof(char),strlen(s),file);
free(s);
fclose(file);
cJSON_Delete(root);
return ;
}
2.解析
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file = NULL;
int fileSize;
char *jsonStr;
struct stat statBuf; //文件属性结构体
file = fopen(JSON_PATH,"r");
if(file == NULL)
{
perror("fopen");
return;
}
stat(JSON_PATH, &statBuf);
fileSize = statBuf.st_size;
// printf("文件大小为:%d\n",fileSize);
// 分配内存
jsonStr = (char *)malloc(sizeof(char) * fileSize + 1);
bzero(jsonStr,fileSize + 1);
if(fread(jsonStr,fileSize,1,file) == 0)
printf("文件读取失败");
// printf("%s\n",jsonStr);
cJSON *root,*item;
root = cJSON_Parse(jsonStr);
if (!root) {
const char *err = cJSON_GetErrorPtr();
printf("Error before: [%s]", err);
free((void *)err);
free(jsonStr);
return;
}
//cJSON结构体中的数据
// 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 *j_str = NULL;
double j_double = 0.0;
int j_int = 0;
bool j_bool = false;
//解析:"name":"client"
item = cJSON_GetObjectItem(root,"name");
if(item != NULL)
{
//判断是不是字符串
if(item->type == cJSON_String)
{
//获取字符串中的值
j_str = item->valuestring; //浅拷贝 j_str与item->valuestring指向的空间相同
printf("%s\n",j_str);
j_str[0] = 'y';
printf("%s\n",j_str); //ylient
printf("%s\n",item->valuestring); //ylient
j_str = malloc(strlen(item->valuestring) + 1);
strcpy(j_str,item->valuestring); //深拷贝
j_str[0] = 'c';
printf("%s\n",j_str); //client
printf("%s\n",item->valuestring); //ylient
free(j_str);
}
}
// 类型判断
/* 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_CreateNumber": 9999999
item = cJSON_GetObjectItem(root,"cJSON_CreateNumber");
if(item != NULL)
{
//判断是不是数字
if(item->type == cJSON_Number)
{
j_int = item->valueint;
printf("%d\n",j_int); //9999999
}
}
// "cJSON_CreateNull": null
item = cJSON_GetObjectItem(root,"cJSON_CreateNull");
if(item != NULL)
{
if(item->type == cJSON_NULL)
{
j_str = cJSON_Print(item); //深拷贝 Free the char* when finished.
printf("%s\n",j_str);
free(j_str);
}
}
// "cJSON_CreateTrue": true
item = cJSON_GetObjectItem(root,"cJSON_CreateTrue");
if(item != NULL)
{
if(item->type == cJSON_True)
{
j_str = cJSON_Print(item); //由于bool类型结构体中没有给出,所以使用字符串代替
printf("%s\n",j_str);
free(j_str);
}
}
// "cJSON_CreateBool0": false
item = cJSON_GetObjectItem(root,"cJSON_CreateBool0");
if(item != NULL)
{
if(item->type == cJSON_False)
{
j_str = cJSON_Print(item);
printf("%s\n",j_str);
free(j_str);
}
}
printf("%d-----------------------------------\n",__LINE__);
// "color": ["red", "green", "blue"]
item = cJSON_GetObjectItem(root,"color");
if(item != NULL)
{
if (item->type == cJSON_Array)
{
int size = cJSON_GetArraySize(item); //获取数组中元素个数
for(int i=0;i<size;i++)
{
cJSON *obj = cJSON_GetArrayItem(item,i);
if(obj != NULL && obj->type == cJSON_String)
{
printf("color : %s\n",obj->valuestring);
}
}
}
}
printf("%d-----------------------------------\n",__LINE__);
item = cJSON_GetObjectItem(root,"color");
if(item != NULL)
{
//获取孩子节点
cJSON *arr = item->child; // 获得 "red"
while (arr) {
if (arr->type == cJSON_String) {
printf("color : %s\n", arr->valuestring);
}
// 获取下一个元素
arr = arr->next;
}
}
printf("%d-----------------------------------\n",__LINE__);
// "address": {
// "南方": {
// "street": "成华大道",
// "city": "四川成都"
// },
// "北方": {
// "street": "长安街",
// "city": "北京"
// }
// }
item = cJSON_GetObjectItem(root,"address");
if(item != NULL)
{
cJSON *val = NULL;
cJSON *south = cJSON_GetObjectItem(item,"南方");
cJSON *north = cJSON_GetObjectItem(item,"北方");
if(south != NULL)
{
val = cJSON_GetObjectItem(south,"city");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(south,"street");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
if(north != NULL)
{
val = cJSON_GetObjectItem(north,"city");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(north,"street");
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
}
printf("%d-----------------------------------\n",__LINE__);
cJSON *val;
item = cJSON_GetObjectItem(root,"address");
if(item != NULL)
{
//获取孩子第一个孩子节点
cJSON *obj = item->child; //"南方": { "street": "成华大道", "city": "四川成都" }
while(obj)
{
if(obj->type == cJSON_Object)
{
val = obj->child;
while(val)
{
if(val->type == cJSON_String)
printf("%s\n",val->valuestring);
// 通过next可以自由获取里面的元素了
val = val->next;
}
}
obj = obj->next; //获取下一组元素
}
}
printf("%d-----------------------------------\n",__LINE__);
// "links": [{
// "name": "Google",
// "url": "http://www.google.com"
// }, {
// "name": "Baidu",
// "url": "http://www.baidu.com"
// }]
item = cJSON_GetObjectItem(root,"links"); //获取数组对象item [{},{}]
cJSON *obj;
if(item != NULL)
{
int size = cJSON_GetArraySize(item);
for(int i=0;i<size;i++)
{
obj = cJSON_GetArrayItem(item,i);
if(obj->type == cJSON_Object)
{
val = cJSON_GetObjectItem(obj,"name");
printf("%s\n",val->valuestring);
val = cJSON_GetObjectItem(obj,"url");
printf("%s\n",val->valuestring);
}
}
}
printf("%d-----------------------------------\n",__LINE__);
item = cJSON_GetObjectItem(root,"links");
if (item != NULL)
{
obj = item->child; //{ "name": "Google", "url": "http://www.google.com" }
while(obj)
{
if(obj->type == cJSON_Object)
{
val = obj->child; //获取 "name": "Google"
while(val)
{
if(val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = val->next; //再获取 "url": "http://www.google.com"
}
}
// 获取下一组元素
obj = obj->next;
}
}
printf("%d-----------------------------------\n",__LINE__);
// "Languages": [["USA", "American English"], ["UK", "British English"]]
cJSON *arr;
item =cJSON_GetObjectItem(root,"Languages"); //[[],[]]
if(item != NULL)
{
if(item->type == cJSON_Array)
{
int size1 = cJSON_GetArraySize(item);
for(int i=0;i<size1;i++)
{
arr = cJSON_GetArrayItem(item,i);
if(arr->type == cJSON_Array)
{
int size2 = cJSON_GetArraySize(arr);
for(int j=0;j<size2;j++)
{
val = cJSON_GetArrayItem(arr,j);
if(val != NULL && val->type == cJSON_String)
printf("%s\n",val->valuestring);
}
}
}
}
}
printf("%d-----------------------------------\n",__LINE__);
item = cJSON_GetObjectItem(root,"Languages");
if (item != NULL)
{
arr = item->child;
while(arr)
{
if (arr->type == cJSON_Array)
{
val = arr->child;
while(val)
{
if(val->type == cJSON_String)
printf("%s\n",val->valuestring);
val = val->next;
}
}
arr = arr->next;
}
}
// char *s = cJSON_Print(root);
// printf("%s\n",s);
// free(s);
free(jsonStr);
fclose(file);
cJSON_Delete(root);
return ;
}
3.修改
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file = NULL;
int fileSize;
char *jsonStr;
char *s ;
struct stat statBuf; //文件属性结构体
file = fopen(JSON_PATH,"r");
if(file == NULL)
{
perror("fopen");
return;
}
stat(JSON_PATH, &statBuf);
fileSize = statBuf.st_size;
// printf("文件大小为:%d\n",fileSize);
// 分配内存
jsonStr = (char *)malloc(sizeof(char) * fileSize + 1);
bzero(jsonStr,fileSize + 1);
if(fread(jsonStr,fileSize,1,file) == 0)
printf("文件读取失败");
cJSON *root = cJSON_Parse(jsonStr);
// "name": "client" ----> "name": "server"
// "cJSON_CreateTrue": true, ----> "cJSON_CreateTrue": false
// "cJSON_CreateFalse": false, ----> "cJSON_CreateFalse": true
// "cJSON_CreateBool": true, ----> "cJSON_CreateBool": false
// "cJSON_CreateBool0": false, ----> "cJSON_CreateBool0": true
// "cJSON_CreateNumber": 9999999 ----> "cJSON_CreateNumber": 66
cJSON_ReplaceItemInObject(root, "name", cJSON_CreateString("server"));
cJSON_ReplaceItemInObject(root,"cJSON_CreateNumber",cJSON_CreateNumber(66));
cJSON_ReplaceItemInObject(root,"cJSON_CreateTrue",cJSON_CreateFalse());
cJSON_ReplaceItemInObject(root,"cJSON_CreateFalse",cJSON_CreateTrue());
cJSON_ReplaceItemInObject(root,"cJSON_CreateBool",cJSON_CreateBool(0));
cJSON_ReplaceItemInObject(root,"cJSON_CreateBool0",cJSON_CreateBool(10));
s = cJSON_Print(root);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
// "color": ["red", "green", "blue"] ---> "color": ["yellow", "black", "white"]
cJSON *item;
item = cJSON_GetObjectItem(root,"color");
if(item != NULL)
{
cJSON_ReplaceItemInArray(item,0,cJSON_CreateString("yellow"));
cJSON_ReplaceItemInArray(item,1,cJSON_CreateString("black"));
cJSON_ReplaceItemInArray(item,2,cJSON_CreateString("white"));
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
/*
"address": {
"南方": {
"street": "成华大道", --->"street": "天府三街"
"city": "四川成都" --->"city": "Chengtu"
},
"北方": {
"street": "长安街", --->"street": "祈年大街"
"city": "北京" --->"city": "Peking"
}
}
*/
cJSON *north,*south;
item = cJSON_GetObjectItem(root,"address");
if(item != NULL)
{
south = cJSON_GetObjectItem(item,"南方");
if(south != NULL && south->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(south,"street",cJSON_CreateString("天府三街"));
cJSON_ReplaceItemInObject(south,"city",cJSON_CreateString("Chengtu"));
}
north = cJSON_GetObjectItem(item,"北方");
if(north != NULL && north->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(north,"street",cJSON_CreateString("祈年大街"));
cJSON_ReplaceItemInObject(north,"city",cJSON_CreateString("Peking"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
/*
"links": [{
"name": "Google", --->"name": "Bing"
"url": "http://www.google.com" --->"url": "https://cn.bing.com/"
}, {
"name": "Baidu", --->"name": "搜狗"
"url": "http://www.baidu.com" --->"url": "https://www.sogou.com/"
}]
*/
cJSON *obj;
item = cJSON_GetObjectItem(root,"links");
if(item != NULL)
{
obj = cJSON_GetArrayItem(item,0);
if(obj != NULL && obj->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(obj,"name",cJSON_CreateString("Bing"));
cJSON_ReplaceItemInObject(obj,"url",cJSON_CreateString("https://cn.bing.com/"));
}
obj = cJSON_GetArrayItem(item,1);
if(obj != NULL && obj->type == cJSON_Object)
{
cJSON_ReplaceItemInObject(obj,"name",cJSON_CreateString("搜狗"));
cJSON_ReplaceItemInObject(obj,"url",cJSON_CreateString("https://www.sogou.com/"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
// "Languages": [["USA", "American English"], ["UK", "British English"]]
// --->"Languages": [["Fr", "French"], ["GER", "German"]]
cJSON *arr;
item = cJSON_GetObjectItem(root,"Languages");
if(item != NULL && item->type == cJSON_Array)
{
arr = cJSON_GetArrayItem(item,0);
if(arr != NULL && arr->type == cJSON_Array)
{
cJSON_ReplaceItemInArray(arr,0,cJSON_CreateString("Fr"));
cJSON_ReplaceItemInArray(arr,1,cJSON_CreateString("French"));
}
arr = cJSON_GetArrayItem(item,1);
if(arr != NULL && arr->type == cJSON_Array)
{
cJSON_ReplaceItemInArray(arr,0,cJSON_CreateString("GER"));
cJSON_ReplaceItemInArray(arr,1,cJSON_CreateString("German"));
}
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
free(jsonStr);
fclose(file);
cJSON_Delete(root);
}
4.删除
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include "cJSON.h"
#define JSON_PATH "./config.json"
void main(int argc, char const *argv[])
{
FILE *file = NULL;
int fileSize;
char *jsonStr,*s;
struct stat statBuf; //文件属性结构体
file = fopen(JSON_PATH,"r");
if(file == NULL)
{
perror("fopen");
return;
}
stat(JSON_PATH, &statBuf);
fileSize = statBuf.st_size;
// printf("文件大小为:%d\n",fileSize);
// 分配内存
jsonStr = (char *)malloc(sizeof(char) * fileSize + 1);
bzero(jsonStr,fileSize + 1);
if(fread(jsonStr,fileSize,1,file) == 0)
printf("文件读取失败");
// /* Remove/Detatch items from Arrays/Objects. */
// extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);//获取
// extern void cJSON_DeleteItemFromArray(cJSON *array,int which);//删除
// extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
// extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
cJSON *root,*item;
root = cJSON_Parse(jsonStr);
/* 删除: "name": "client" */
// 使用这个函数直接进行删除
// cJSON_DeleteItemFromObject(root, "name"); // 通过键进行删除
cJSON *tmp = cJSON_DetachItemFromObject(root,"name"); //通过键获取"client" ,且原root中去掉了"name": "client"
s = cJSON_Print(tmp);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
/*
"address": {
"南方": {
"street": "成华大道",
"city": "四川成都"
},
"北方": {
"street": "长安街",
"city": "北京"
}
}
*/
// --->
/*
"南方": {
"street": "成华大道"
}
*/
//删除"南方"对象中的city
cJSON *south,*north;
item = cJSON_GetObjectItem(root,"address");
if(item != NULL && item->type == cJSON_Object)
{
south = cJSON_GetObjectItem(item,"南方");
cJSON_DeleteItemFromObject(south,"city");
s = cJSON_Print(south);
printf("%s\n",s);
free(s);
}
printf("%d-----------------------------------\n",__LINE__);
//直接删除"北方"对象
if(item != NULL && item->type == cJSON_Object)
{
cJSON_DeleteItemFromObject(item,"北方");
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
// "color": ["red", "green", "blue"]
// 删除 "red" "green"
item = cJSON_GetObjectItem(root,"color");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
if(item != NULL && item->type == cJSON_Array)
{
int size = cJSON_GetArraySize(item);
printf("%d\n",size);
cJSON_DeleteItemFromArray(item,0);
cJSON_DeleteItemFromArray(item,0);
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
// "Languages": [["USA", "American English"], ["UK", "British English"]]
//删除 ["USA", "American English"]
//删除 "British English"
cJSON *arr;
item = cJSON_GetObjectItem(root,"Languages");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
if(item != NULL && item->type == cJSON_Array)
{
//元素删除后 下标改变
cJSON_DeleteItemFromArray(item,0); //删除 ["USA", "American English"]
arr = cJSON_GetArrayItem(item,0); //获取首元素 [ ["UK", "British English"] ]
cJSON_DeleteItemFromArray(arr,1); //删除 "British English"
s = cJSON_Print(arr);
printf("%s\n",s);
free(s);
}
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
/*
"links": [{
"name": "Google",
"url": "http://www.google.com"
}, {
"name": "Baidu",
"url": "http://www.baidu.com"
}]
*/
//删除 { "name": "Google", "url": "http://www.google.com" }
//再删除 "name": "Baidu"
cJSON *obj;
item = cJSON_GetObjectItem(root,"links");
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
if(item != NULL && item->type == cJSON_Array)
{
cJSON_DeleteItemFromArray(item,0); //删除{ "name": "Google", "url": "http://www.google.com" }
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
obj = cJSON_GetArrayItem(item,0);
cJSON_DeleteItemFromObject(obj,"name"); //删除 "name": "Baidu"
s = cJSON_Print(obj);
printf("%s\n",s);
free(s);
}
printf("%d-----------------------------------\n",__LINE__);
s = cJSON_Print(item);
printf("%s\n",s);
free(s);
printf("%d-----------------------------------\n",__LINE__);
s = cJSON_Print(root);
printf("%s\n",s);
free(s);
free(jsonStr);
fclose(file);
cJSON_Delete(root);
}
5.编译运行
gcc xx.c -lcjson -lm
./a.out
八、总结
json数据主要由两种方式构成
- 对象 、数组
- 对象中可以包含键值对、数组、对象等
- 数组中包含值,值可以是数字、true、false、字符串、对象、数组等
在cJSON库中
-
创建对象通过cJSON_CreateObject();
-
创建数组通过cJSON_CreateArray();
-
向对象添加对象通过cJSON_AddItemToObject();
-
向数组中添加元素通过cJSON_AddItemToArray();
-
删除指定的对象通过cJSON_DeleteItemFromObject();
-
删除数组中的元素通过cJSON_DeleteItemFromArray();
可以向指定的键或数组中添加的以下值
- 字符串:cJSON_CreateString();
- null:cJSON_CreateNull();
- 数字:cJSON_CreateNumber();
- true/false:cJSON_CreateBool();
- true:cJSON_CreateTrue();
- false:cJSON_CreateFalse();
参考:
动态库、静态库的制作
从零开始的 JSON 库教程
CC++ 使用cjson库 操作Json格式文件(创建、插入、解析、修改、删除)