JSON常用函数小总结

JSON概念

 JSON: JavaScript 对象表示法( JavaScript Object Notation) 。是一种轻量级的数据交换格式。 它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式, 但是也使用了类似于C语言家族的习惯( 包括C、 C++、 C#、 Java、 JavaScript、 Perl、 Python等) 。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写, 同时也易于机器解析和生成(一般用于提升网络传输速率)。

JSON结构体解析

typedef struct cJSON //cJSON结构体
{     
       struct cJSON *next,*prev;              /* 遍历数组或对象链的前向或后向链表指针*/
       struct cJSON *child;                   /* 数组或对象的孩子节点*/
       int type;                              /* key的类型*/
       char *valuestring;                     /* 字符串值*/
       int valueint;                          /* 整数值*/
       double valuedouble;                    /* 浮点数值*/
       char *string;                          /* key的名字*/
} cJSON;

反序列所用函数(将json解析为程序所用的格式)

cJSON *cJSON_Parse(const char *value);
/*作用:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体
返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL*/
例子:cJSON * cjson =cJSON_Parse(保存JSON字符串的变量,char *类型)

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/*作用:获取JSON字符串字段值
返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL*/
补充:int age = cJSON_GetObjectItem(cjson,"age")->valueint;    //解析整型
可在后加参数,准确返回一个数据类型的值。
valuestring;    //解析字符串          valueint;    //解析整型
valuedouble;    //解析双浮点型        type;     //解析逻辑值---输出逻辑值对应的宏定义数值

int    cJSON_GetArraySize(cJSON *array);
//获取cjson对象数组成员的个数
cJSON *cJSON_GetArrayItem(cJSON *array,int item);
//根据下标获取cjosn对象数组中的对象
//两者联合使用十分nice

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); 
//清除结构体

例子

    cJSON *ADD    = cJSON_CreateObject();                //创建一个对象
    cJSON_AddStringToObject(ADD,"country","China");    //添加字符串 
    cJSON_AddNumberToObject(ADD,"zip-code",123456);    //添加整型数字

    cJSON *SUB  = cJSON_CreateArray();                //创建一个数组
    cJSON_AddStringToObject(SUB,"","政治");         //添加字符串到数组
     cJSON_AddStringToObject(SUB,"","数学");
    cJSON_AddStringToObject(SUB,"","英语");
    cJSON_AddStringToObject(SUB,"","专业课");
    cJSON_AddItemToObject(TCP,"subject",SUB);        //添加数组到对象

以上便是常用的json函数,可做参考

附练习:

使用cJSON库对下面的JSON文件进行反序列化操作。ver和login的子节点直接打印即可,data的数据节点解析后形成链表存储(将下面内容存为文件,读取后解析,推荐使用标准IO(fread)解析)。

解析完成后,再利用解析完的变量和链表,序列化为json字符串直接打印即可。

注意:上面的所有val值都是string类型,解析出来存到节点前,需要根据type的类型来进行转换,按照相应的类型存储到共用体中。

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

程序代码

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
#include "list.h"
#include <stdbool.h>

union val_t {
    bool a1;
    int a2;
    float a3;
};
struct data //创建结构体
{
    int key;
    int type;
    union val_t val;
    struct list_head list;
};

int main(int argc, char const *argv[])
{
    FILE *f;                           //创建文件流
    long len;                          //文件长度
    char *content;                     //保存文件内容
    f = fopen("./test.json", "rb");    //打开保存的json文件
    fseek(f, 0, SEEK_END);             //将文件流指针移动到最后
    len = ftell(f);                    //确定偏移长度
    fseek(f, 0, SEEK_SET);             //将文件刘指针移动到最前
    content = (char *)malloc(len + 1); //开辟空间,准备读取json信息
    fread(content, 1, len, f);         //读取json信息,保存到content中
    struct data dat1;                  //创建结构体等待使用
    cJSON *root = NULL;                //用于序列化json
    cJSON *item = NULL;                //暂村某一类的json
    cJSON *okpl = NULL;                //用于data数据暂村
    root = cJSON_Parse(content);       //将文件序列化,由root存储
    struct list_head head;             //head里面存首尾的地址
    INIT_LIST_HEAD(&head);
    if (!root)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    } //判断是否读取成功
    else
    {
        item = cJSON_GetObjectItem(root, "ver");
        char *verbuf = item->valuestring;
        printf("ver: %s\n", item->valuestring);

        cJSON *item_login = NULL;
        item_login = cJSON_GetObjectItem(root, "login");

        item = cJSON_GetObjectItem(item_login, "user");
        char *userbuf = item->valuestring;
        printf("user: %s\n", item->valuestring);
        item = cJSON_GetObjectItem(item_login, "pwd");
        char *pwdbuf = item->valuestring;
        printf("pwd: %s\n", item->valuestring);

        item = cJSON_GetObjectItem(root, "data");          //获取ver对象
        for (int i = 0; i < cJSON_GetArraySize(item); i++) //对data的每一个元素进行处理
        {
            struct data *node = (struct data *)malloc(sizeof(struct data));
            okpl = cJSON_GetArrayItem(item, i);                   //拆开data元素,按下标获取数据
            node->key = cJSON_GetObjectItem(okpl, "key")->valueint; 
            //获取data中下标为1的,中key的数据
            node->type = cJSON_GetObjectItem(okpl, "type")->valueint;
            if (node->type == 1)
            {
                char *op1 = cJSON_GetObjectItem(okpl, "val")->valuestring;
                node->val.a1 = atol(op1);
            }
            if (node->type == 2)
            {
                char *op1 = cJSON_GetObjectItem(okpl, "val")->valuestring;
                node->val.a2 = atol(op1);
            }
            if (node->type == 3)
            {
                char *op1 = cJSON_GetObjectItem(okpl, "val")->valuestring;
                node->val.a3 = atol(op1);
            }
            list_add(&node->list, &head);
        }
        struct list_head *pos;
        struct data *tmp;
        list_for_each(pos, &head)
        {
            tmp = list_entry(pos, struct data, list);
            printf("key = %d", tmp->key);
            if (tmp->type == 1)
            {
                printf("type=%d,val=%d", tmp->type, tmp->val.a1);
            }
            if (tmp->type == 2)
            {
                printf("type=%d,val=%d", tmp->type, tmp->val.a2);
            }
            if (tmp->type == 3)
            {
                printf("type=%d,val=%.2f", tmp->type, tmp->val.a3);
            }
            printf("\n");
        }


        printf("------------序列化-------------------------\n");
        cJSON *TCP = cJSON_CreateObject();            //创建一个对象
        cJSON_AddStringToObject(TCP, "name", verbuf); //添加字符串

        cJSON *ADD = cJSON_CreateObject(); //创建一个对象
        cJSON_AddStringToObject(ADD, "user", userbuf);
        cJSON_AddStringToObject(ADD, "pwd", pwdbuf);
        cJSON_AddItemToObject(TCP, "login", ADD);

        cJSON *STU = cJSON_CreateArray(); //创建一个数组

        list_for_each(pos, &head)
        {
            tmp = list_entry(pos, struct data, list);

            if (tmp->type == 1)
            {
                cJSON *a1 = cJSON_CreateObject();                //创建一个对象
                cJSON_AddNumberToObject(a1, "key", tmp->key);    //添加整型数字
                cJSON_AddNumberToObject(a1, "type", tmp->type);  //添加整型数字
                cJSON_AddNumberToObject(a1, "val", tmp->val.a1); //添加整型数
                cJSON_AddItemToArray(STU, a1);                   //添加对象到数组中
            }
            else if (tmp->type == 2)
            {
                cJSON *a2 = cJSON_CreateObject();                //创建一个对象
                cJSON_AddNumberToObject(a2, "key", tmp->key);    //添加整型数字
                cJSON_AddNumberToObject(a2, "type", tmp->type);  //添加整型数字
                cJSON_AddNumberToObject(a2, "val", tmp->val.a2); //添加布尔数
                cJSON_AddItemToArray(STU, a2);                   //添加对象到数组中
            }
            else if (tmp->type == 3)
            {
                cJSON *a3 = cJSON_CreateObject();                //创建一个对象
                cJSON_AddNumberToObject(a3, "key", tmp->key);    //添加整型数字
                cJSON_AddNumberToObject(a3, "type", tmp->type);  //添加整型数字
                cJSON_AddNumberToObject(a3, "val", tmp->val.a3); //添加浮点数
                cJSON_AddItemToArray(STU, a3);                   //添加对象到数组中
            }
        }

        cJSON_AddItemToObject(TCP, "data", STU); //添加数组到对象中
        char *json_data = cJSON_Print(TCP);      //JSON数据结构转换为JSON字符串
        printf("%s\n", json_data);               //输出字符串

        cJSON_Delete(TCP); //清除结构体
    }

    /*
    
    cJSON * root = NULL;
    root = cJSON_Parse(content);     
    if (!root) 
    {
        printf("Error before: [%s]\n",cJSON_GetErrorPtr());
    }
    else
    {
        printf("%s\n", "有格式的方式打印Json:");           
        printf("%s\n\n", cJSON_Print(root));
    }
 */
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值