最小简单 json的c库(cJSON)的使用

590 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情

简单讲一下json

写一个最简单的 json格式:{}。啥也没有的json。
节点由两部分构成:“key”:“obj”
那么就能得到最精简的一个json了:{"Nm":"qshp"}
最常用的自然是数组,数组的语法:["a","b","c"],其中每一个双引号都是一个对象,可以用来存储我们的列表。

Cjson简单介绍

c下使用非常广泛的json库就是cjon,当然可能是我用的少,其他的也没用过。用cjson几年,用到项目中一直很稳定,没出过问题,仅仅改过源码中浮点数的精度,其他的用起来顺手的很。

下载源码地址:github.com/DaveGamble/…

更多因为不可抗力,也可以通过以下地址下载:gitee.com/mirrors/cJS…

本章讲一下cjson接口的简单使用,基本能够满足项目使用了。 关于json数据格式的语法,可以学习:www.runoob.com/json/json-t…

下载的源码包结构: image.png 我们只需要 cjson的源码和头文件即可。

/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    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;

通篇到底的最重要的json结构体,所有结构都会使用这个数据结构,作为接口传参的句柄。

接口介绍

cJSON_Version:打印我们使用的cjson库的版本号
cJSON_Parse:解析json字符串。
cJSON_Delete:解析json成功后的句柄,不使用的时候一定需要删除一下。
cJSON_GetArraySize:获取数组的个数。
cJSON_GetArrayItem:按照序列号得到数组特定的节点。
cJSON_Is****:用于判断节点的类型,是否有效,数字或者空 等等等等。
cJSON_GetObjectItem:通过查找对象是否存在某个string为关键字的节点,大小写不敏感。
cJSON_GetObjectItemCaseSensitive:通过查找对象是否存在某个string为关键字的节点,大小写敏感。
cJSON_HasObjectItem:解析节点值前判断一下,防止异常。
cJSON_Print:可用于打印json句柄的字符串。

使用演示

创建一个测试用的字符串,保存到本地配置文件,与源码同一目录下,如下: image.png

测试代码:

#include<stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "cJSON.h"

//    fprintf(stdout,"\t\t\t\t[Radix Sort]inputNum:");


int main(int argc, char** argv)
{
    char Buf[4096] = {0};
    int bfd = open("tt",O_RDWR);
    read(bfd,Buf,4095);
    fprintf(stdout,"\t\t\t\t read json Buf:[%s]",Buf);
    close(bfd);

    //解析我们读到的Json字符串
    cJSON* JsonMain = cJSON_Parse(Buf);
    if(JsonMain == NULL) {
        fprintf(stdout,"\t\t\t\t parse fail:[%s]",cJSON_GetErrorPtr());
        return 1;
    }

    //得到数组对象的Json句柄
    cJSON* JsonArr = cJSON_GetObjectItem(JsonMain,"items");

    //得到数组的个数,便于遍历全部节点
    int ArrCnt = cJSON_GetArraySize(JsonArr);
    cJSON* OneNode = NULL;
    for(int i = 0;i < ArrCnt;i++){
        OneNode = cJSON_GetArrayItem(JsonArr,i);
        fprintf(stdout,"\n\n index arr[%d]\n",i);
        fprintf(stdout,"\t nm:     [%s]\n",cJSON_GetObjectItem(OneNode,"nm")->valuestring);
        fprintf(stdout,"\t val:    [%s]\n",cJSON_GetObjectItem(OneNode,"val")->valuestring);
        fprintf(stdout,"\t type:   [%d]\n",cJSON_GetObjectItem(OneNode,"t")->valueint);
        fprintf(stdout,"\t time:   [%s]\n",cJSON_GetObjectItem(OneNode,"tm")->valuestring);
        fprintf(stdout,"\t quality:[%d]\n",cJSON_GetObjectItem(OneNode,"q")->valueint);
    }
    cJSON_Delete(JsonMain);
    return 0;
}

跑一圈的结果: image.png

cJSON的接口写的,我觉得非常好用且冗余较少,最近一年好像没更新,使用的过程中,可以去源码里面多理解下写法,对我们技术是有好处的。