Json是一种轻量级的数据交换格式。
文章目录
- 1. cJson介绍
- 2. 解析json数据
- 3. 封装json数据
- 4. 从文件中读取json
1. cJson介绍
JSON对象是一个无序的"名称/值"键值对的集合:
以"{“开始,以”}"结束,允许嵌套使用;
每个名称和值成对出现,名称和值之间使用":"分隔;
键值对之间用","分隔
这些字符前后允许存在无意义的空白符;
对于键值,可以有如下值:
一个新的json对象
数组:使用"[“和”]"表示
数字:直接表示,可以是整数,也可以是浮点数
字符串:使用引号"表示
字面值:false、null、true中的一个(必须是小写)
cJSON是一个用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点。
地址:https://github.com/DaveGamble/cJSON
在工程中,只需要包含这两个文件即可:
2. 解析json数据
一个实例:
#include <iostream>
extern "C" {
#include <stdio.h>
#include "cJSON.h"
}
// 定义一个Json数据
char *message =
"{ \
\"name\":\"XiaoMing\", \
\"age\": 22, \
\"weight\": 60, \
\"address\": \
{ \
\"country\": \"China\",\
\"zip-code\": 111111\
}, \
\"skill\": [\"c\", \"Java\", \"Python\"],\
\"student\": false \
}";
int main(void)
{
// 实例化
cJSON* cjson_test = NULL;
cJSON* cjson_name = NULL;
cJSON* cjson_age = NULL;
cJSON* cjson_weight = NULL;
cJSON* cjson_address = NULL;
cJSON* cjson_address_country = NULL;
cJSON* cjson_address_zipcode = NULL;
cJSON* cjson_skill = NULL;
cJSON* cjson_student = NULL;
int skill_array_size = 0, i = 0;
cJSON* cjson_skill_item = NULL;
// 解析整段Json数据
cjson_test = cJSON_Parse(message);
if (cjson_test == NULL)
{
printf("parse fail.\n");
return -1;
}
// 依次根据名称提取JSON数据(键值对)
cjson_name = cJSON_GetObjectItem(cjson_test, "name");
cjson_age = cJSON_GetObjectItem(cjson_test, "age");
cjson_weight = cJSON_GetObjectItem(cjson_test, "weight");
printf("name: %s\n", cjson_name->valuestring);
printf("age:%d\n", cjson_age->valueint);
printf("weight:%.1f\n", cjson_weight->valuedouble);
// 解析嵌套json数据
cjson_address = cJSON_GetObjectItem(cjson_test, "address");
cjson_address_country = cJSON_GetObjectItem(cjson_address, "country");
cjson_address_zipcode = cJSON_GetObjectItem(cjson_address, "zip-code");
printf("address-country:%s\naddress-zipcode:%d\n", cjson_address_country->valuestring, cjson_address_zipcode->valueint);
// 解析数组
cjson_skill = cJSON_GetObjectItem(cjson_test, "skill");
skill_array_size = cJSON_GetArraySize(cjson_skill);
printf("skill:[");
for (i = 0; i < skill_array_size; i++)
{
cjson_skill_item = cJSON_GetArrayItem(cjson_skill, i);
printf("%s,", cjson_skill_item->valuestring);
}
printf("\b]\n");
// 解析布尔型数据
cjson_student = cJSON_GetObjectItem(cjson_test, "student");
if (cjson_student->valueint == 0)
{
printf("student: false\n");
}
else
{
printf("student:error\n");
}
return 0;
}
结果如下:
3. 封装json数据
一个实例:
#include <iostream>
extern "C" {
#include <stdio.h>
#include "cJSON.h"
}
int main(void)
{
cJSON* cjson_test = NULL;
cJSON* cjson_address = NULL;
cJSON* cjson_skill = NULL;
char* str = NULL;
/* 创建一个JSON数据对象(链表头结点) */
cjson_test = cJSON_CreateObject();
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
cJSON_AddStringToObject(cjson_test, "name", "XiaoMing");
/* 添加一条整数类型的JSON数据(添加一个链表节点) */
cJSON_AddNumberToObject(cjson_test, "age", 22);
/* 添加一条浮点类型的JSON数据(添加一个链表节点) */
//cJSON_AddNumberToObject(cjson_test, "weight", 60); //提示找不到标识符
/* 添加一个嵌套的JSON数据(添加一个链表节点) */
cjson_address = cJSON_CreateObject();
cJSON_AddStringToObject(cjson_address, "country", "China");
//cJSON_AddNumberToObject(cjson_address, "zip-code", 111111);
cJSON_AddItemToObject(cjson_test, "address", cjson_address);
/* 添加一个数组类型的JSON数据(添加一个链表节点) */
cjson_skill = cJSON_CreateArray();
cJSON_AddItemToArray(cjson_skill, cJSON_CreateString("C"));
cJSON_AddItemToArray(cjson_skill, cJSON_CreateString("Java"));
cJSON_AddItemToArray(cjson_skill, cJSON_CreateString("Python"));
cJSON_AddItemToObject(cjson_test, "skill", cjson_skill);
/* 添加一个值为 False 的布尔类型的JSON数据(添加一个链表节点) */
cJSON_AddFalseToObject(cjson_test, "student");
/* 打印JSON对象(整条链表)的所有数据 */
str = cJSON_Print(cjson_test);
printf("%s\n", str);
return 0;
}
结果如下:
4. 从文件中读取json
一个实例:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include<sys/stat.h> //stat
#include "cJSON.h"
#define FILENAME "./map.json"
typedef struct
{
int x;
int y;
}arr;
//解析一个结构数组
int cJSON_to_struct_array(char *text, arr worker[])
{
cJSON *json,*arrayItem,*item,*object;
int i = 0;
json=cJSON_Parse(text); //parse
if (!json)
{
printf("Error before: [%s]\n",cJSON_GetErrorPtr());
}
else
{
arrayItem=cJSON_GetObjectItem(json,"arr"); // 获取json对象中的arr节点
if(arrayItem!=NULL)
{
int size=cJSON_GetArraySize(arrayItem); //获取数组大小
printf("cJSON_GetArraySize: size=%d\n",size);
for(i=0;i<size;i++)
{
printf("i=%d\n",i);
object=cJSON_GetArrayItem(arrayItem,i);
item=cJSON_GetObjectItem(object,"x"); // 获取json对象中的firstName节点
if(item!=NULL)
{
printf("cJSON_GetObjectItem: type=%d, valueint is %d\n",item->type,item->valueint);
memcpy(worker[i].x,item->valueint,strlen(item->valueint));
}
else
{
printf("cJSON_GetObjectItem: get age failed\n");
}
item=cJSON_GetObjectItem(object,"y");
if(item!=NULL)
{
printf("cJSON_GetObjectItem: type=%d, valueint=%d\n",item->type,item->valueint);
worker[i].y=item->valueint;
}
else
{
printf("cJSON_GetObjectItem: get age failed\n");
}
}
}
printf("\n\n");
for(i=0; i<sizeof(worker) / sizeof(worker[0]) ;i++) //获取数组长度
{
printf("i=%d",i);
printf("x=%d,y=%d\n",
worker[i].x,
worker[i].y);
}
cJSON_Delete(json);
}
return 0;
}
// 文件大小
size_t get_file_size(const char *filepath)
{
if(NULL == filepath)
return 0;
struct stat filestat;
memset(&filestat,0,sizeof(struct stat));
/*获取文件信息*/
if(0 == stat(filepath,&filestat))
return filestat.st_size;
else
return 0;
}
// 读取文件
void read_file(char *filename)
{
FILE *fp;
arr worker[4]={{0}};
/*get file size*/
size_t size = get_file_size(filename);
if(0 == size)
{
printf("get_file_size failed!!!\n");
}
/*malloc memory*/
char *buf = malloc(size+1);
if(NULL == buf)
{
printf("malloc failed!!!\n");
}
memset(buf,0,size+1);
fp=fopen(filename,"rb");
fread(buf,1,size,fp);
fclose(fp);
printf("read file %s complete, size=%d.\n",filename,size);
cJSON_to_struct_array(buf, worker);
free(buf);
}
// main
int main(int argc, char **argv)
{
read_file(FILENAME);
// // 实例化
// cJSON* cjson_x = NULL;
// cJSON* cjson_y = NULL;
// // 依次根据名称提取JSON数据(键值对)
// cjson_x = cJSON_GetObjectItem(cjson_x, "x");
// cjson_y = cJSON_GetObjectItem(cjson_y, "y");
// printf("x:%d\n", cjson_x->valueint);
// printf("y:%d\n", cjson_y->valueint);
return 0;
}
在ubuntu编写makefile如下:
main:main.c
gcc cJSON.c main.c -o main -lm
clean:
rm main
这样就能从json文件中读取数据了。
参考:http://t.csdn.cn/M7ClB
以上。