JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。
该程序使用了linux内核链表来进行的操作,内核链表的详细使用点击这里
本程序另外还需,json.h、json.c和list.h,可以自行准备,也可以私信我。
json.txt
{
"ver": "1.0",
"login": {
"user": "zhangsan",
"pwd": "123456"
},
"data": [{
"key": 1,
"type": 2,
"val": "10"
},
{
"key": 2,
"type": 1,
"val": "0"
},
{
"key": 3,
"type": 3,
"val": "22.5"
}
]
}
main.c
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include "cJSON.h"
#include "list.h"
char jsonStr[1024];
int len;
union val_t{
int b;
int i;
double f;
};
struct data{
int key;
int type;
union val_t val;
struct list_head list;
};
struct data datas[5];
struct list_head head;
//用来输出只含有一层的嵌套的json对象
void printJSON(cJSON *root,char *user,char *pwd){
for(int i=0;i<cJSON_GetArraySize(root);i++){
cJSON *item = cJSON_GetArrayItem(root,i);
if(i==0){
strcpy(user,item->valuestring);
}else{
strcpy(pwd,item->valuestring);
}
printf("%s->",item->string);
printf("%s\n",cJSON_Print(item));
}
}
//用来输出两层的json嵌套对象,并将其中的数据保存至链表
void printArray(cJSON *root){
//第一个for循环,获取数组对象内部的每一个对象
for(int i=0;i<cJSON_GetArraySize(root);i++){
cJSON *item = cJSON_GetArrayItem(root,i);
//第二层for循环,获取每一个对象内部的每一个属性
for(int j=0;j<cJSON_GetArraySize(item);j++){
cJSON *item2 = cJSON_GetArrayItem(item,j);
printf("%s->",item2->string);
printf("%s\n",cJSON_Print(item2));
if(!strcmp(item2->string,"key")){
datas[i].key = item2->valueint;
}else if(!strcmp(item2->string,"type")){
datas[i].type = item2->valueint;
}else if(!strcmp(item2->string,"val")){
if(datas[i].type == 1){
datas[i].val.i = atoi(item2->valuestring);
}else if(datas[i].type == 2){
datas[i].val.b = atoi(item2->valuestring);
}else if(datas[i].type == 3){
datas[i].val.f = atof(item2->valuestring);
}
}
}
//将每一个节点插入链表
list_add(&datas[i].list,&head);
len++;
printf("\n");
}
}
int main(int argc, char const *argv[])
{
char ver[2][5]={0};
char user[16]={0};
char pwd[16]={0};
FILE* fd = fopen("json.txt","r");
//初始化链表
INIT_LIST_HEAD(&head);
//读取文件内容,存放至jsonStr
fread(jsonStr,sizeof(jsonStr),1,fd);
cJSON *root = NULL;
cJSON *item = NULL;
//开始反序列化(解析json代码)
//从json代码中获取json对象
root = cJSON_Parse(jsonStr);
if(!root){
printf("err\n");
}else{
//printf("%s\n",cJSON_Print(root));
struct data data1;
//根据对象的键获取对应的值
item = cJSON_GetObjectItem(root,"ver");
strcpy(ver[0],item->string);
printf("%s->",ver[0]);
strcpy(ver[1],item->valuestring);
printf("%s\n",cJSON_Print(item));
item = cJSON_GetObjectItem(root,"login");
//调用上方实现的函数1
printJSON(item,user,pwd);
item = cJSON_GetObjectItem(root,"data");
//调用上方实现的函数2
printArray(item);
struct list_head *pos;
struct data *tmp;
//遍历查看json数据是否插入到链表中
list_for_each(pos,&head){
tmp = list_entry(pos,struct data,list);
printf("key=%d type=%d \n",tmp->key,tmp->type);
if(tmp->type == 1){
printf("val:%d\n",tmp->val.i);
}
if(tmp->type == 2){
printf("val:%d\n",tmp->val.i);
}
if(tmp->type == 3){
printf("val:%d\n",tmp->val.i);
}
}
}
fclose(fd);
//生成并打印json(生成json文件对的对象)
//这里根据我们要生成的json对象创建我们可能会用到的对象
cJSON *root2 = cJSON_CreateObject();
cJSON *item2 = cJSON_CreateObject();
cJSON *item3 = cJSON_CreateArray();
//直接在根目录下插入一个普通对象
cJSON_AddItemToObject(root2,ver[0],cJSON_CreateString(ver[1]));
//这里也是在根目录下插入一个普通对象
cJSON_AddItemToObject(root2,"login",item2);
//在item2中插入两个属性
cJSON_AddItemToObject(item2,"user",cJSON_CreateString(user));
cJSON_AddItemToObject(item2,"pwd",cJSON_CreateString(pwd));
//在根目录下插入item3数组对象
cJSON_AddItemToObject(root2,"data",item3);
//在数组下方插入三个对象
for (int i = 0; i < len; i++)
{
cJSON *next2 = cJSON_CreateObject();
//创建一个json对象
cJSON_AddNumberToObject(next2,"key",datas[i].key);
cJSON_AddNumberToObject(next2,"type",datas[i].type);
if(datas[i].type==1)
cJSON_AddNumberToObject(next2,"val",datas[i].val.b);
else if(datas[i].type==2)
cJSON_AddNumberToObject(next2,"val",datas[i].val.i);
else if(datas[i].type==3)
cJSON_AddNumberToObject(next2,"val",datas[i].val.f);
//将每个对象所需要的值分别插入
cJSON_AddItemToArray(item3,next2);
//将创建好的对象插入数组
}
printf("%s\n",cJSON_Print(root2));
return 0;
}