目录

了解json

json数据类型

格式规范

json格式校验

JSON基本操作

JSON解析(反序列化)

JSON构造(序列化)

练习


了解json

JSON: JavaScript 的对象表示法( JavaScript Object Notation)。是一种轻量级的数据交换格式。
        JSON采用完全独立于语言的文本格式, 但是也使用了类似于C语言家族的习惯( 包括C、 C++、 C#、 Java、 JavaScript、 Perl、 Python等)。JSON 具有自我描述性, 语法简洁, 易于理解。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写, 同时也易于机器解析和生成(一般用于提升网络传输速率)。
        JSON 解析器和 JSON 库支持许多不同的编程语言。 JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。 由于这种相似性, 无需解析器, JavaScript 程序能够使用内建的 eval() 函数, 用 JSON 数据来生成原生的 JavaScript 对象,而在C语言中我们一般使用cJSON解析器来进行json字符串的解析。

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的结构体

注:
1.json的数据类型在源码实现中和具体的编程语言有关,比如boolean在C中并没有相应的类型,C相关的实现库可能会用0和1表示。
2.number的数据虽然是相当于C中的int类型,但是也可以存放浮点型数据等内容。

格式规范

  • json以大括号起始和结尾
  • 内容都是以键值对的形式存在
  • 所有的键都是字符串
  • 值的类型不一定,属于JavaScript 的基本数据类型
  • 每个键值对以,分割
  • 最后一个键值对不加逗号

json格式校验

在线JSON校验格式化工具(Be JSON)

JSON基本操作

Json序列化:可以理解为利用程序生成Json字符串的过程。

Json反序列化:可以理解为利用程序将已有的Json字符串解析出我们需要的值的过程。

JSON解析(反序列化)

cJSON解析器对象的实现采用了树形结构,每个对象是树的一个节点,每个节点由cJSON这个结构体组成,对象中的元素也由cJSON这个结构体组成。同一层的对象和元素是双向链表结构,由next和prev指针链接。不同层的对象或元素由child指针链接起来。type表示对象或元素类型,string表示对象或节点的名称。元素的值存储在valuestring, valueint和valuedouble中,cJSON.h中有详细的注释。解析json我们一般借助以下函数:

cJSON *cJSON_Parse(const char *value);
//功能:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体
//返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULLcJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
//功能:获取JSON字符串字段值
//返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULLint cJSON_GetArraySize(cJSON *array);
//功能:获取数组成员对象个数
//返回值:数组成员对象个数int cJSON_HasObjectItem(cJSON *object,const char *string)
//功能:判断cjson对象中是否有某键
//返回值:如果有返回1 否则返回0 cJSON *cJSON_GetArrayItem(cJSON *array,int item);
//根据下标获取cjson对象数组中的对象void  cJSON_Delete(cJSON *c);
/*作用:释放位于堆中cJSON结构体内存
返回值:无*/char *cJSON_GetErrorPtr(void);
//获取错误字符串char  *cJSON_Print(cJSON *item);
//从cjson对象中获取有格式的json对象,打印到终端char  *cJSON_PrintUnformatted(cJSON *item);
//从cjson对象中获取无格式的json对象,打印到终端

JSON构造(序列化)

CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
//创建对象---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
//创建数组---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
//创建整型数组
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
//创建双浮点型数组
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
//在对象中添加null
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
//在对象中添加true
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
//在对象中添加false
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
//在对象中添加数字
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
//在对象中添加字符串
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
//在对象中添加项目
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
//在数组中添加项目
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
//JSON数据结构转换为JSON字符串---有格式
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
//JSON数据结构转换为JSON字符串---无格式
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
//清除结构体

练习

1.对以下json字符串进行序列化。

2.使用cJSON库对下面的将下面内容存为json文件,读取后解析,进行反序列化操作。

{"ver": "1.0","login": {"user": "zhangsan","key": "123456"},"data": [{"key": 1,"type": 2,"val": "10"},{"key": 2,"type": 1,"val": "0"},{"key": 3,"type": 3,"val": "22.5"}]
}

序列化例程:

// 1.构造根节点rootcJSON * root =  cJSON_CreateObject();// 2.给 root 添加 ver 的子节点,子节点类型是 stringcJSON_AddItemToObject(root, "ver", cJSON_CreateString("1.0"));// 3.给 root 添加 login 的子节点,子节点类型是 objectcJSON * object1 =  cJSON_CreateObject();cJSON_AddItemToObject(root, "login", object1);// 4.给 login 节点添加 user 和 key 节点cJSON_AddItemToObject(object1, "user", cJSON_CreateString("zhangsan"));cJSON_AddItemToObject(object1, "key", cJSON_CreateString("123456"));// 5.创建数组节点cJSON *array  = cJSON_CreateArray();// 6.将数组data加入根节点中cJSON_AddItemToObject(root, "data", array);// 7.往data数组节点遍历增加项list_for_each(p, &head){tmp = list_entry(p, struct data, list);// 7.1 创建数组data的子节点(此时还没放进数组data中)cJSON *tmp_son = cJSON_CreateObject();// 7.2 往数组data字节点中增加key和typecJSON_AddItemToObject(tmp_son, "key", cJSON_CreateNumber(tmp->key));cJSON_AddItemToObject(tmp_son, "type", cJSON_CreateNumber(tmp->type));// 7.3 往数组data字节点中增加val// 7.3.1 处理valchar buf_tmp[32] = "";switch (tmp->type){case 1:sprintf(buf_tmp, "%d", tmp->val.b);break;case 2:sprintf(buf_tmp, "%d", tmp->val.i);break;case 3:sprintf(buf_tmp, "%0.2f", tmp->val.f);break;}// 7.3.2 将处理好的val即string基本类型添加到数组data的字节点中cJSON_AddItemToObject(tmp_son, "val", cJSON_CreateString(buf_tmp));// 7.3.3 将字节点tmp_son增加到数组data中cJSON_AddItemToArray(array, tmp_son);}// 8.打印cJSON验证printf("\n打印Json字符串验证:\n");printf("%s\n", cJSON_Print(root));

反序列化例程:

#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "cJSON.h"
#include "cJSON.c"typedef int BOOL;union val_t {BOOL b;int i;float f;
};struct data
{int key;int type;union val_t val;struct list_head list;
};int main(int argc, char const *argv[])
{/* ----------读取文件---------- */FILE *fd = NULL;fd = fopen("./test.json", "r");if (NULL == fd){perror("fopen failed.");return -1;}char buf[500] = "";if (fread(buf, 500, 1, fd) < 0){perror("fread failed.");return -1;}/* -----------JSON的反序列化----------- */// 1.取出对象objectcJSON *object = cJSON_Parse(buf);if (NULL == object){printf("Error before: [%s]\n", cJSON_GetErrorPtr());return -1;}// 2.取出对象object下的节点ver和logincJSON *item = cJSON_GetObjectItem(object, "ver");printf("ver: %s\n", item->valuestring); cJSON *item_login = cJSON_GetObjectItem(object, "login");// 3.从login节点中取出user和key两子节点item = cJSON_GetObjectItem(item_login, "user");printf("user: %s\n", item->valuestring);item = cJSON_GetObjectItem(item_login, "key");printf("key: %s\n", item->valuestring);// 4.取出对象object下的数组节点dataitem = cJSON_GetObjectItem(object, "data");// 5.链表初始化struct list_head head;INIT_LIST_HEAD(&head);// 6.遍历取出数组中每个项并加到链表里面去for (int i = 0; i < cJSON_GetArraySize(item); i++){// 6.1 根据下标从数组节点中取出第i个节点cJSON *value = cJSON_GetArrayItem(item, i);// 6.2 从第i个节点中取子节点key和typecJSON *value_key = cJSON_GetObjectItem(value, "key");cJSON *value_type = cJSON_GetObjectItem(value, "type");// 6.3 malloc出结构体指针nodestruct data *node = (struct data *)malloc(sizeof(struct data));// 6.4 通过指针对结构体赋值node->key = value_key->valueint;node->type = value_type->valueint;cJSON *value_val = cJSON_GetObjectItem(value, "val");switch (value_type->valueint){case 1:node->val.b = atoi(value_val->valuestring);break;case 2:node->val.i = atoi(value_val->valuestring);break;case 3:node->val.f = atof(value_val->valuestring);break;}// 7.加到链表里由链表存储list_add(&node->list, &head);}/* ~~~~~~~~~~~~~~~~~~~~~~~遍历输出链表,验证已经由链表存储~~~~~~~~~~~~~~~~~~~~~~~ */printf("\n遍历输出链表, 验证已经由链表存储:\n");struct list_head *p;struct data *tmp;list_for_each(p, &head){tmp = list_entry(p, struct data, list);printf("key = %d, type = %d, ", tmp->key, tmp->type);switch (tmp->type){case 1:printf("val = %d\n", tmp->val.b);break;case 2:printf("val = %d\n", tmp->val.i);break;case 3:printf("val = %0.2f\n", tmp->val.f);break;}}return 0;
}

注意事项:

编译cJSON库时候,gcc需要增加 -l m选项,动态链接math库。

JSON学习及cJSON使用相关推荐

  1. json格式与cJSON函数库

    json的格式 键/值对 key:value,用半角冒号分割 文档对象 JSON对象写在花括号中,可以包含多个键/值对. 数组 JSON 数组在方括号中书写: 数组成员可以是对象,值,也可以是数组(只 ...

  2. java对象转Json学习

    java对象转Json学习 json多用于数据存储.交换与传输,json相比于xml更小,更快,更容易解析 对象的表示方法 #java Person p = new Person(); p.setNa ...

  3. c语言解析json代码举例,CJSON 实例

    cJSON: 一个用c写的一个简单好用的JSON解析器 cJSON库 1.json的数据结构 c语言中json数据是采用链表存储的 typedef struct cJSON { struct cJSO ...

  4. 开源项目学习:cJSON库的学习和使用(上)---以天气JSON数据为例

    目录 1. cJSON源码的获取 2. JSON 的认识 3. 实践 3.1 解析一个 JSON 对象,获取其中项目(实时天气数据解析) 3.2 解析一个 JSON 数组,获取其中项目(未来或历史天气 ...

  5. Json学习总结(4)——Json基础知识回顾

    一.什么是JSON? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation); JSON 是轻量级的文本数据交换格式; JSON 具有自我描述性,更 ...

  6. Json - 学习/实践

    Json介绍 1.php中的Json简介 1. 学习目的 1.掌握并且能使用Json数据格式进行通信交互 2.理解Json数据格式和serialize序列化,XML以及数组的区别 2. Json起源 ...

  7. JSON学习(一)——了解JSON

    认识 一.第一印象 JSON:JavaSrcipt Object Notation:轻量级的数据交换格式. 理解:前后端分离开发中作为数据传递与交互的一种数据格式 二.深入学习 JSON 指的是 Ja ...

  8. JSON学习1-什么是JSON

    什么是JSON JSON(JavaScript Object Notation)指的是 JavaScript 对象表示法,是一种轻量级的数据交换格式.它的优点是易于人的阅读和编写,同时也易于及其解析和 ...

  9. JSON学习笔记-处理空白字符(使用 SSE4.2 优化字符串扫描)

    背景:一些JSON含有大量的空白字符(whitspace),在解析JSON时需要跳过这些空白字符. 那么如果我们只是简单的进行处理,当遇在输入流中到这四种空白字符( ,\t,\n,\r,)时,直接跳过 ...

最新文章

  1. cocoapods更新
  2. 关于IE8.0 Internet Explorer 已经为了帮助保护您的计算机而关闭此网页 解决方法
  3. 职称计算机隐藏桌面图标,2018年职称计算机考试WindowsXP操作题(1)
  4. ue4导入倾斜摄影_干货 | 6款倾斜摄影裸眼3D采集软件推荐给大家
  5. Oracle表的修改和删除以及回收站操作
  6. sql timestep 秒数后6位_excel中,如何截取身份证号后6位?前4位?或者中间8位?...
  7. c++中vector用法(涵盖算法题中知识点)
  8. Spring 的狭义与广义
  9. GDB 调试命令讲解 2-转
  10. 电子游戏发展史话——《doom启示录》读后感(三)
  11. 在线扑克运营商在 WSOP 赛事开幕当天遭到 DDoS 攻击
  12. C++学习心得:引用的详解
  13. 「经济读物」小狗钱钱
  14. 关于如何设置网页自动切换背景图片
  15. 教师计算机培训考勤表,之江汇平台的使用-信息技术培训
  16. 联邦学习与安全多方计算
  17. 激动我心的感觉――我的○五年元月求职经历[ZT]
  18. Text Mesh Pro 1.4.0实现图片组合伤害数字
  19. 实时数仓利器之Doris
  20. 进程 Android架构  Android Runtime  Libraries framework简介 Framework的范围 framework简介范围基础 Linux入门介绍

热门文章

  1. MySql随机查询一条数据
  2. rpm,tgz文件格式
  3. 雅克比迭代法的例子matlab,MATLAB样例之雅克比迭代法
  4. 【笔记】【机器学习基础】1.7 鸢尾花分类
  5. Matlab非线性优化函数fmincon
  6. mysql重复数据只取一条数据_SQL删除重复数据只保留一条
  7. c语言字符串corrupt,primary label corrupt; using backup故障修复
  8. 防火墙Mangle-连接标记和包标记-从零开始学RouterOS系列09
  9. CTO下午茶:找到海神的三叉戟,打破运维的魔与咒
  10. 解决win7安装VMTools失败