一文看懂JSON的创建/解析

json官方网站:http://www.json.org/

[1] JSON概述

JSON:JavaScript Object Notation(JavaScript对象表示法)

  1. 是一种轻量级的数据交换格式,是存储和交换文本信息的语法,类似XML。JSON比XML更小、更快、更易解析。
  2. JSON采用完全独立于语言的文本表达格式,但是也使用了类似C语言家族的习惯(包括C\C++\C#\Java\Perl\python等)
  3. 这些特性使得JSON成为了理想的数据交换语言,易于阅读和编写,同时也易于解析和生成(一般用于提升网络传输速率)
  4. 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下载与安装

  1. 下载链接cJSON:https://github.com/DaveGamble/cJSON
  2. 解压:JSON库十分的简单,下载的JSON代码不需要编译生成库,只需要加载cJSON.c、cJSON.h两个文件即可。
  3. 测试文件,编译:gcc cJSON.c xxx.c -o test -lm (添加数学库)

API:生成JSON文件

创建一个空的对象文档,即 { }extern cJSON* cJSON_CreateObject(void);
释放JSONcJSON_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;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值