博客:

前言

众所周知,JSON是一种轻量级的数据格式,应用广泛。在C/C++应用中也常常作为配置文件或者数据的存储,因此JSON文件的生成和解析是必备知识。

cJSON

cJSON是使用ANSI C编写的超轻量级的JSON解析器,因此在C中也常常是不二之选。

地址:

下载到本地后json解析,进行编译:

$ make

执行完成后即可在当前目录下得到.a和.so。

当然你也可以只下载cJSON.c和cJSON.h自己编译成静态库或动态库,可参考前期文章《如何制作静态库》和《动态库的制作和两种使用方式》。编译后的.a保留调试信息也只有不过43k。

关键数据结构

cJSON的关键数据结构如下:

typedef struct cJSON {  //cJSON结构体
       struct cJSON*next,*prev;           /*后驱节点和前驱节点*/
       struct cJSON *child;                   /*孩子节点*/
       int type;                                     /* 键的类型*/
       char *valuestring;                       /*字符串值*/
       int valueint;                                /* 整数值*/
       double valuedouble;                    /* 浮点数值*/
       char *string;                               /* 键的名字*/
} cJSON;

json是一种组织良好的数据格式,因而JSON中的内容解析后json解析,都可以通过以上数据结构进行处理。

例如,对于下面的json内容:

{
    "name":"编程珠玑",
    "site":"https://www.yanbinghu.com",
    "age":1
}

解析后,site将会是name的next节点,并且它的键类型是字符串。

常用接口函数

cJSON *cJSON_Parse(const char *value);

用于将字符串解析成json对象,若失败则返回NULL。

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

用于获取json对象中的某个节点,若失败,返回NULL,成功则返回该节点对象。

void   cJSON_Delete(cJSON *c);

用于释放json对象相关内存。

char *cJSON_Print(const cJSON *item);

用于将JSON对象转换成字符串,记得最后释放相关内存。

JSON文件解析准备

解析JSON文件可大致分为以下几个步骤:

为了将JSON文件的内容读取到,需要知道文件的大小:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
size_t get_file_size(const char *filepath)
{
    /*check input para*/
    if(NULL == filepath)
        return 0;
    struct stat filestat;
    memset(&filestat,0,sizeof(struct stat));
    /*get file information*/
    if(0 == stat(filepath,&filestat))
        return filestat.st_size;
    else
        return 0;
}

然后申请一段内存,将文件中的文本读取到中:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
char *read_file_to_buf(const char *filepath)
{
    /*check input para*/
    if(NULL == filepath)
    {
        return NULL;
    }
    /*get file size*/
    size_t size = get_file_size(filepath);
    if(0 == size)
        return NULL;

    /*malloc memory*/
    char *buf = malloc(size+1);
    if(NULL == buf)
        return NULL;
    memset(buf,0,size+1);

    /*read string from file*/
    FILE *fp = fopen(filepath,"r");
    size_t readSize = fread(buf,1,size,fp);
    if(readSize != size)
    {
        /*read error*/
        free(buf);
        buf = NULL;
    }

    buf[size] = 0;
    return buf;
}

再根据前面提到的解析流程,我们的JSON预解析函数如下:

cJSON *prepare_parse_json(const char *filePath)
{
    /*check input para*/
    if(NULL == filePath)
    {
        printf("input para is NULLn");
        return NULL;
    }
    /*read file content to buffer*/
    char *buf = read_file_to_buf(filePath);
    if(NULL == buf)
    {
        printf("read file to buf failedn");
        return NULL;
    }
    /*parse JSON*/
    cJSON *pTemp = cJSON_Parse(buf);
    free(buf);
    buf = NULL;
    return pTemp;
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注