[1] JSON概述
JSON:JavaScript Object Notation(JavaScript对象表示法)
- 是一种轻量级的数据交换格式,是存储和交换文本信息的语法,类似XML。JSON比XML更小、更快、更易解析。
- JSON采用完全独立于语言的文本表达格式,但是也使用了类似C语言家族的习惯(包括C\C++\C#\Java\Perl\python等)
- 这些特性使得JSON成为了理想的数据交换语言,易于阅读和编写,同时也易于解析和生成(一般用于提升网络传输速率)
- JSON解析器和JSON库支持许多种不同的编程语言。JSON文本格式在语法上与创建JavaScript对象的代码相同。由于这种相似性,无需解析器,JavaScript程序能够使用内建的eval()函数,用于JSON数据来生成原生的JavaScript对象。
[2] 什么样的是JSON呢?
数据在key/value对中,key/value用冒号分开
花括号保存对象,也称为一个文档对象
方括号保存数组,每个数组成员用逗号隔开,并且每个数组成员可以是文档对象或键值对
{
# key和value必须是字符串类型; key和value之间用冒号分开
"name" : "矮大紧",
"sex" : "male",
"high" : "180cm",
"家电" : {"电视机":"长虹", "手电筒":"三星"}, # {...}表示是一个对象
"grils": ["蓉儿", "黄儿", "船儿"], # [...]表示是一个数组,数组中的成员用逗号隔开
# 数组成员可以是文档对象或键值对
"stars":[
{"name":"Faye", "address":"北京"},
{"name":"Andy", "address":"香港"},
{"name":"Eddie", "address":"台湾"},
],
}
使用JSON格式化工具http://www.bejson.com/jsonviewernew,格式化后,点击格式化左面的"视图"按钮。
[3]JSON下载与安装
- 下载链接cJSON:https://github.com/DaveGamble/cJSON
- 解压:JSON库十分的简单,下载的JSON代码不需要编译生成库,只需要加载cJSON.c、cJSON.h两个文件即可。
- 测试文件,编译:gcc cJSON.c xxx.c -o test -lm (添加数学库)
API:生成JSON文件
创建一个空的对象文档,即 { } | extern cJSON* cJSON_CreateObject(void); |
释放JSON | cJSON_Delete(json); |
创建一个值类型的数据cJSON* | |
extern cJSON* cJSON_CreateNumber(double num); | |
extern cJSON* cJSON_CreateString(const char * string); | |
创建数组 | extern cJSON* cJSON_CreateArray(void); |
创建Int类型的数组 | cJSON* cJSON_CreateIntArray(const int* number,int count); |
创建string类型的数组 | cJSON* cJSON_CreateStringArray(const int* number,int count); |
向数组中添加数据 | void cJSON_AddItemToArray(cJSON* array,cJSON* item); |
JSON嵌套 | |
向对象中增加键值对 | cJSON_AddItemToObject(root,“rows”,值类型数据相关函数()); |
向对象中增加数组 | cJSON_AddItemToObject(root,“rows”,cJSON_CreateArray() |
向数组中增加对象 | cJSON_AddItemToArray(rows,sJSON_CreateObject()); |
#include "cJSON.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
cJSON* json = cJSON_CreateObject(); //创建一个json空对象,即 {}
//向json对象中添加键值对
cJSON_AddStringToObject(json,"name","Tom"); //等价于cJSON_AddItemToObject(json,"name",cJSON_CreateString("Tom"));
cJSON_AddNumberToObject(json,"age",24); //等价于cJSON_AddItemToObject(json,"age",cJSON_CreateNumber(24));
//向json对象中添加键值对:key=love,value=空数组
cJSON* Arr = NULL;
cJSON_AddItemToObject(json,"love",Arr = cJSON_CreateArray()); // love:[]
//向数组中添加元素
cJSON_AddItemToArray(Arr,cJSON_CreateString("basketball"));
cJSON_AddItemToArray(Arr,cJSON_CreateString("swim"));
//嵌套关系
cJSON* subObj = NULL;
cJSON_AddItemToArray(Arr,subObj = cJSON_CreateObject());
cJSON* games_Arr = NULL;
cJSON_AddItemToObject(subObj,"games",games_Arr = cJSON_CreateArray());
cJSON_AddItemToArray(games_Arr,cJSON_CreateString("LOL"));
cJSON_AddItemToArray(games_Arr,cJSON_CreateString("CF"));
//将创建好的json文件保存到本地文件
char* buf = cJSON_Print(json); //将json结构体转换成buf
FILE* fp = fopen("new.json","w+");
fwrite(buf,1,strlen(buf),fp);
free(buf);
fclose(fp);
//释放json对应的内存空间
cJSON_Delete(json);
return 0;
}
上面代码生成的JSON文件
{
"name": "Tom",
"age": 24,
"love": [ "basketball","swim",{"games": ["LOL","CF"]} ]
}
API:解析JSON文件
解读json结构体
/* cJSON Types: */
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
可以根据type获得的信息:
1.判断cJSON是否是一个数组
cJSON* node = cJSON_GetObjectItem(json,"family"); //
if(node->type = cJSON_Array) //if(cJSON_IsArray(node))
2.判断cJSON数组中存放的是字符串
还是数字
[数组]?、[数组中存放的是字符串?数字?]
if(cJSON_GetArrayItem(node,i)->type == cJSON_String)
printf("%s\n",cJSON_GetArrayItem(node,i)->valuestring);
else if(cJSON_GetArrayItem(node,i)->type == cJSON_Number)
printf("%s\n",cJSON_GetArrayItem(node,i)->valuedouble);
根据key找value | |
将char*提取到json结构体 | cJSON* json = cJSON_Parse(string); |
在json中,查找key是string的项 | cJSON* cJSON_GetObjectItem(cJSON* object,const char* string); |
在json中,判断是否有key是string的项 | int cJSON_HasObjectItem(cJSON* object,const char* string); |
| |
获得数组中元素的个数 | int cJSON_GetArraySize(cJSON* array); |
获得数组中位置为index的成员 | cJSON* cJSON_GetArrayItem(cJSON* array,int index); |
遍历数组 | cJSON_ArrayForEach(pos,head) |
示例代码:解析本地文件
待解析的new.json文件
{
"name": "Tom",
"age": 24,
"love": [ "basketball","swim",{"games": ["LOL","CF"]} ]
}
代码执行结果:
[gjw@localhost Test]$ ./parse
name = Tom
age = 24
love: [basketball ,swim ,{ games:[LOL CF ] }]
#include "cJSON.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//将本地json文件中的内容,读入content
FILE* f;
long len;//文件长度
char *content;//文件内容
f=fopen("new.json","rb");
fseek(f,0,SEEK_END);
len=ftell(f);
fseek(f,0,SEEK_SET);
content=(char*)malloc(len+1);
fread(content,1,len,f);
fclose(f);
cJSON *json = cJSON_Parse(content); //string--->json
cJSON* name = cJSON_GetObjectItem(json,"name");
printf("name = %s\n",name->valuestring);
cJSON* age = cJSON_GetObjectItem(json,"age");
printf("age = %d\n",age->valueint);
cJSON* love = cJSON_GetObjectItem(json,"love");
if(love == NULL)
{
printf("not find love\n");
exit(1);
}
printf("love: [");
for(int i=0;i<cJSON_GetArraySize(love);i++)
{
cJSON* node = cJSON_GetArrayItem(love,i);
if(node->type == cJSON_String)
printf("%s ,",node->valuestring);
else
{
cJSON* Arr = cJSON_GetObjectItem(node,"games");
if(Arr==NULL)
{
exit(1);
}
printf("{ games:[");
for(int i=0;i<cJSON_GetArraySize(Arr);i++)
{
cJSON* node = cJSON_GetArrayItem(Arr,i);
if(node->type== cJSON_String)
printf("%s ",node->valuestring);
}
printf("] }");
}
}
printf("]");
printf("\n");
return 0;
}