JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。
JSON 语法规则
- JSON是以大括号起始和结尾
- 内容都是以键值对的形式存在
- 所有的键都是字符串
- 值的类型不一定,属于JavaScript 的基本数据类型
- 每个键值对以都好分割,最后一个键值对不加逗号
JSON 数据类型
- number:和JavaScript的number完全一致;相当于C中的int类型
- boolean:就是JavaScript的true或false;相当于c++中的bool类型
- string:就是JavaScript的string;相当于c++的string类型
- null:就是JavaScript的null;相当于C的NULL类型
- array:就是JavaScript的Array表示方式——[];相当于C的数组
- object:就是JavaScript的{ ... }表示方式。相当于C++的类或者C的结构体
使用cJSON解析JSON
使用cJSON库对下面的JSON文件进行反序列化操作。ver和cloud的节点直接打印即可,data的数据节点解析后形成链表存储
{
"ver": "1.0",
"cloud": {
"password": "12345678",
"mpassword": "12345678910"
},
"data": [{
"key": 1,
"type": 2,
"val": "10"
},
{
"key": 2,
"type": 1,
"val": "0"
},
{
"key": 3,
"type": 3,
"val": "22.5"
}
]
}
为了方便存取选用Linux内核链表
typedef int BOOL;
union val_t {
int i_val;
BOOL b_val;
float f_val;
};
struct data {
int key;
int type;
union val_t val;
struct list_head list;
};
下面是main函数
int main(int argc, const char *argv[])
{
FILE *fp = fopen("./test.txt","r+"); //使用fopen函数打开读取test.txt的内容
if(fp == NULL)
{
perror("fopen err");
return -1;
}
char buf[512] = {0};
if(fread(buf,sizeof(buf),512,fp) < 0) //把test.txt的内容读到buf字符数组里
{
perror("fread err");
return -1;
}
struct list_head head;
INIT_LIST_HEAD(&head);
cJSON * root = cJSON_Parse(buf); //将JSON字符串转换为JSON结构体
cJSON * item = NULL; //CJSON对象
if(root == NULL)
{
printf("Error befor:[%s]\n",cJSON_GetErrorPtr());
}
else
{
item = cJSON_GetObjectItem(root,"ver"); //解析对象
printf("ver:%s\n",cJSON_Print(item)); //打印对象里的内容
item = cJSON_GetObjectItem(root,"cloud"); //解析对象
item = cJSON_GetObjectItem(item,"password"); //解析对象节点里的内容
printf("password:%s\n",cJSON_Print(item));
item = cJSON_GetObjectItem(root,"cloud"); //解析对象
item = cJSON_GetObjectItem(item,"mpassword"); //解析对象节点里的内容
printf("mpassword:%s\n",cJSON_Print(item));
cJSON * Buf = cJSON_GetObjectItem(root,"data"); //解析数组
int len = cJSON_GetArraySize(Buf); 获取数组成员个数
int i;
for(i=0 ; i<len ; i++)
{
struct data *node = (struct data *)malloc(sizeof(struct data)); //创建链表节点
int key;
key = cJSON_GetObjectItem(cJSON_GetArrayItem(Buf,i),"key")->valueint;
node->key = key; //解析数组中的整型数字并存入链表里
int typ;
typ = cJSON_GetObjectItem(cJSON_GetArrayItem(Buf,i),"type")->valueint;
node->type = typ; //解析数组中的整型数字并存入链表里
char *vale;
vale = cJSON_GetObjectItem(cJSON_GetArrayItem(Buf,i),"val")->valuestring;
if(node->type == 1) //解析数组中的布尔型
{
node->val.b_val = 0;
}
else if(node->type == 2) //解析数组中的整形
{
node->val.i_val = atoi(vale);
}
else if(node->type == 3) //解析数组中的浮点型
{
node->val.f_val = atof(vale);
}
list_add(&(node->list),&head); //存入链表
}
struct list_head *pos;
struct data *tme;
//利用内核链表循环便利出来
list_for_each(pos,&head)
{
tme = list_entry(pos,struct data,list);
if(tme->type == 2)
{
printf("key:%d type:%d val:%d\n",tme->key,tme->type,tme->val.i_val);
}
else if(tme->type == 1)
{
printf("key:%d type:%d val:%d\n",tme->key,tme->type,tme->val.b_val);
}
else
{
printf("key:%d type:%d val:%.2f\n",tme->key,tme->type,tme->val.f_val);
}
}
}
close(fp);
cJSON_Delete(cjson);
return 0;
}
注意:上面的所有val值都是string类型,解析出来存到节点前,需要根据type的类型来进行转换,按照相应的类型存储到共用体中。