【C/C++专栏】cJSON的API介绍和使用

目录

前言

一,cJSON 数据类型

二,cJSON 结构体

三,创建 Json 项

四,往 JSON 项中添加数据

五,从 JSON 父项中删除  JSON 子项

六,更新 JSON 项的指定位置数据

七,拷贝 JSON 项

八,比较两个 JSON 项是否相等

九,判断当前 JSON 项的类型

十,获取当前 JSON 项的 value 值

十一,删除 JSON 项(重点)

十二,解析 JSON 项 

十三,获取 JSON 项的序列化值

十四,获取当前 cJSON 版本

十五,JSON 钩子模块(了解就行)

十六,案例答疑解惑

1,测试读写的 test.json 文件内容(文件路径 E:\test.json)

2,所需要的头文件

3,写 Json 文件接口实现

4,读 Json 文件接口实现

总结


前言

cJSON 是用C语言编写的一个超轻量,可移植,单文件的 JSON 解析器,它是个开源的项目,它只有 cJSON.h 和 cJSON.c 两个文件,使用时只需要在对应的 include src 目录添加进去就可以使用了,cJSON 下载地址

一,cJSON 数据类型

  • << 是左移运算符,左移运算符介绍
  • 这是 cJSON 用于类型判断的自定义宏,只需要了解是啥类型就行

二,cJSON 结构体

  • 整个 JSON 文档里的数据其实就是一个树形结构,每个节点是一个双向链表,child 指向子 JSON 项
  • string 表示的是 键值对中 key 的名称

三,创建 Json 项

  • 常用的七个创建指定 数据类型 JSON 项

  •  创建 数组 的同时进行初始化

  • 以下不常用 

四,往 JSON 项中添加数据

  • 针对 数组 通过 item 传入 JSON 项(数组或对象)
  • 针对 对象 通过 键(string)值(item)对 传入 JSON 项(数组或对象)

  • 往已有的 JSON 对象中添加指定 键(name)值(第三个参数)对 类型数据

  • 以下不常用

五,从 JSON 父项中删除  JSON 子项

  • 通过 指针下标 或 键值 从父 JSON 项中删除指定项
  • sensitive 表示对传入的 键值 大小写敏感

六,更新 JSON 项的指定位置数据

  • 针对 数组 传入的 下标(which) 不能超过数组长度
  • 针对 对象 传入的 子对象(item)或 键值(string) 要存在
  • sensitive 表示对传入的 键值(string) 大小写敏感

七,拷贝 JSON 项

  • 返回值为传入的 JSON项(item)的拷贝值
  • recurse 表示是否递归拷贝,也就是是否拷贝 item 子JSON 项(数组或对象)

八,比较两个 JSON 项是否相等

  • case_sensitive 表示比对的 JSON项(数组或对象) 的 键值 是否区分大小写

九,判断当前 JSON 项的类型

十,获取当前 JSON 项的 value 值

  • 传入 item(数组或对象)会先判断其是否为接口名称类型,不是返回 NULL 是返回其 value 值

  • 可以用来检查 JSON 文档是否格式写错

  • 传入键值(string)返回其值(子JSON项),sensitive表示区分大小写
  • 判断是否存在指定 键值(string)的 子JSON项

  • 以下接口有对应注释进行解释

十一,删除 JSON 项(重点)

  • 一定要记得调用这接口,它会将当前节点及其子节点都会进行删除(内存释放

十二,解析 JSON 项 

  • 第一个经常用来解析 JSON 格式的字符串

  • 以下两个不常用 

十三,获取 JSON 项的序列化值

  • 返回一个带格式化(有换行)的字符串(和JSON文档中的格式一样)

  •  返回一个未格式化(没有换行)的字符串(所有数据都在一行上)

  • prebuffer是指定缓冲区的大小

  • 没用过

十四,获取当前 cJSON 版本

十五,JSON 钩子模块(了解就行)

十六,案例答疑解惑

1,测试读写的 test.json 文件内容(文件路径 E:\test.json)

  {
      "FirstName": "Fu",
      "LastName": "Cong",
      "Age": 24,
      "Address": {
          "Street": "首创悦榕汇",
          "City": "BeiJing",
          "Country": "BeiJing"
      },
      "Phone numbers": [
          "+44 12345",
          678910
      ]
  }

2,所需要的头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

3,写 Json 文件接口实现

void writeJson()
{
    cJSON *obj_root;
    obj_root = cJSON_CreateObject();    //创建根数据对象
    cJSON_AddStringToObject(obj_root,"FirstName","Fu");
    cJSON_AddStringToObject(obj_root,"LastName","Cong");
    cJSON_AddNumberToObject(obj_root, "Age",24);

    cJSON *subObj_addr;
    subObj_addr = cJSON_CreateObject();
    cJSON_AddItemToObject(subObj_addr,"Street",cJSON_CreateString("首创悦榕汇"));
    cJSON_AddItemToObject(subObj_addr,"City",cJSON_CreateString("BeiJing"));
    cJSON_AddItemToObject(subObj_addr,"Country",cJSON_CreateString("BeiJing"));

    cJSON *subObj_arr;
    subObj_arr = cJSON_CreateArray();   //创建数组对象
    cJSON_AddItemToArray(subObj_arr,cJSON_CreateString("+44 12345"));
    cJSON_AddItemToArray(subObj_arr,cJSON_CreateNumber(678910));

    cJSON_AddItemToObject(obj_root,"Address",subObj_addr);
    cJSON_AddItemToObject(obj_root,"Phone numbers",subObj_arr);

    char  *out = cJSON_Print(obj_root);

    FILE *file = fopen("E:\\test.json","w");
    if(file != NULL){
        fputs(out,file);    //写入文件流
        fclose(file);   //关闭文件流
        
        //一定要记得释放内存
        cJSON_Delete(obj_root);
        free(out);
    }
}

效果图如下

4,读 Json 文件接口实现

//返回指定文件的所有内容
char *readFile(char *path)
{
    FILE *file = fopen(path,"r");;
    char *data = NULL;
    long length;    //文件大小
    if(file != NULL){
        //文件打开成功
        fseek(file,0,SEEK_END); //将文件流光标移动到文件末尾
        length = ftell(file);  //获取文件内容的大小(相对于文件开头的位移量来表示)
        data = (char*)malloc((length +1)*sizeof(char));
        rewind(file);   //将文件光标重置到文件开头位置
        length = fread(data,1,length,file);   //一次性读取所有字符串
        data[length] = 0;
        fclose(file);   //关闭文件流
        return data;
    }
    return NULL;
}
//解析从 JSON 文件中读取的数据
void readJson()
{
    char *jsonData = readFile("E:\\test.json");
    if(jsonData == NULL){
        printf("%s","File is empty");
    }

    cJSON *json_root = cJSON_Parse(jsonData);
    if(cJSON_IsObject(json_root)){
        //JSON根数据是对象
        cJSON *subobj_one = cJSON_GetObjectItem(json_root,"FirstName");
        if(cJSON_IsString(subobj_one)){
            printf("%s:%s\n","FirstName",cJSON_GetStringValue(subobj_one));
        }
        cJSON *subobj_two = cJSON_GetObjectItem(json_root,"LastName");
        if(cJSON_IsString(subobj_two)){
            printf("%s:%s\n","LastName",cJSON_GetStringValue(subobj_two));
        }
        cJSON *subobj_three = cJSON_GetObjectItem(json_root,"Age");
        if(cJSON_IsNumber(subobj_three)){
            printf("%s:%2.0f\n","Age",cJSON_GetNumberValue(subobj_three));
        }
        cJSON *subObj_four = cJSON_GetObjectItem(json_root,"Address");
        if(cJSON_IsObject(subObj_four)){
            //子 JSON 项是对象
            cJSON *subSubobj_one = cJSON_GetObjectItem(subObj_four,"Street");
            if(cJSON_IsString(subSubobj_one)){
                
                printf("%s:%s\n","Street",cJSON_GetStringValue(subSubobj_one));
            }
            cJSON *subSubobj_two = cJSON_GetObjectItem(subObj_four,"City");
            if(cJSON_IsString(subSubobj_two)){
                printf("%s:%s\n","City",cJSON_GetStringValue(subSubobj_two));
            }
            cJSON *subSubobj_three = cJSON_GetObjectItem(subObj_four,"Country");
            if(cJSON_IsString(subSubobj_three)){
                printf("%s:%s\n","Country",cJSON_GetStringValue(subSubobj_three));
            }
        }
        cJSON *subArr_one = cJSON_GetObjectItem(json_root,"Phone numbers");
        if(cJSON_IsArray(subArr_one)){
            //子 JSON 项是数组
            int array_size = cJSON_GetArraySize(subArr_one);
            for(int i=0; i< array_size; i++){
                cJSON *arrItem = cJSON_GetArrayItem(subArr_one,i);
                //用 cJSON 自定义的宏判断 JSON 类型
                if(arrItem->type == cJSON_String){
                    printf("%s:%s\n","Phone number1",arrItem->valuestring);
                }
                if(arrItem->type == cJSON_Number){
                    printf("%s:%d\n","Phone number2",arrItem->valueint);
                }
            }
        }
    }else if(cJSON_IsArray(json_root)){
        //JSON根数据是对象
        //和上面类似,根据已知的 JSON 文档内容调用相应 cJSON API 无限套娃
    }

    if(json_root){
        //一定要记得释放内存
        cJSON_Delete(json_root);
        free(jsonData);
    }
}

效果图如下

总结

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉伊卜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值