cJSON快速上手

  • cJSON使用双向链表储存JSON数据,每个节点为一个键值对,键值对由结构体cJSON封装。
  • cJSON使用双向链表头结点的地址作为句柄执行相关操作。

类型

Types

/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False  (1 << 0)
#define cJSON_True   (1 << 1)
#define cJSON_NULL   (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array  (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw    (1 << 7) /* raw json */

cJSON布尔值

typedef int cJSON_bool;

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;

  • String:键值对的key
  • type:值的类型
  • valuestring:指向字符串或cJSON_Raw
  • valueint:储存整数
  • valuedouble:储存浮点数
  • child:指向子对象或数组

判断节点类型

/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);


序列化

创建cJSON项,返回节点地址

/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);

添加项至对象或数组

/* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);

CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);

同时创建、添加项至对象

/* Helper functions for creating and adding items to an object at the same time.
 * They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
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*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);

从数组或对象中删除或分离项

/* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);

cJSON链表转字符串

/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);


反序列化

字符串转cJSON链表

/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);

由key取出对象中的项

/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);

遍历数组中的项

/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);

释放cJSON链表

/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);

示例

测试代码

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

struct Info{
    char* date;
    int tempMax;
    int tempMin;
    int humidity;
    double precip;
    char* text;
};

int main(){
    /********封装JSON***************/

    cJSON* root = cJSON_CreateObject();
    
    cJSON_AddNumberToObject(root,"code",200);
    cJSON_AddStringToObject(root,"time","2023-7-1T16:35+08:00");

    cJSON* day1 = cJSON_CreateObject();
    cJSON_AddStringToObject(day1,"date","2023-7-4");
    cJSON_AddNumberToObject(day1,"tempMax",36);
    cJSON_AddNumberToObject(day1,"tempMin",27);
    cJSON_AddNumberToObject(day1,"humidity",85);
    cJSON_AddNumberToObject(day1,"precip",0.0);
    cJSON_AddStringToObject(day1,"text","阴");

    cJSON* day2 = cJSON_CreateObject();
    cJSON_AddStringToObject(day2,"date","2023-7-5");
    cJSON_AddNumberToObject(day2,"tempMax",31);
    cJSON_AddNumberToObject(day2,"tempMin",27);
    cJSON_AddNumberToObject(day2,"humidity",85);
    cJSON_AddNumberToObject(day2,"precip",0.0);
    cJSON_AddStringToObject(day2,"text","阴");

    cJSON* day3 = cJSON_CreateObject();
    cJSON_AddStringToObject(day3,"date","2023-7-6");
    cJSON_AddNumberToObject(day3,"tempMax",32);
    cJSON_AddNumberToObject(day3,"tempMin",28);
    cJSON_AddNumberToObject(day3,"humidity",80);
    cJSON_AddNumberToObject(day3,"precip",12.6);
    cJSON_AddStringToObject(day3,"text","中雨");

    cJSON* daily = cJSON_CreateArray();
    cJSON_AddItemToArray(daily,day1);
    cJSON_AddItemToArray(daily,day2);
    cJSON_AddItemToArray(daily,day3);

    cJSON_AddItemToObject(root,"daily",daily);

    char* jsonStr = cJSON_Print(root);
    puts("封装的json如下:");
    puts("-------------------------------");
    puts(jsonStr);
    puts("-------------------------------");
    printf("无格式的JSON串:%s\n",cJSON_PrintUnformatted(root));
    puts("-------------------------------");

    cJSON_Delete(root);

    /********解析JSON**********/

    struct Info info;
    cJSON* jsonList = cJSON_Parse(jsonStr);
    if(jsonList == NULL){
        printf("JSON解析出错,错误信息:%s\n",cJSON_GetErrorPtr());
        return -1;
    }
    cJSON* dailyArray = cJSON_GetObjectItem(jsonList,"daily");
    if(dailyArray == NULL && !cJSON_IsArray(dailyArray)){
        printf("dailyArray解析出错,错误信息:%s\n",cJSON_GetErrorPtr());
        return -1;
    }

    int arrSize = cJSON_GetArraySize(dailyArray);
    for(int i = 0; i < arrSize; i++){
        cJSON* obj = cJSON_GetArrayItem(dailyArray,i);
        cJSON* date = cJSON_GetObjectItem(obj,"date");

        if(obj == NULL || date == NULL)
            break;

        if(!strcmp(date->valuestring,"2023-7-6")){
            info.date = date->valuestring;
            info.text = cJSON_GetObjectItem(obj,"text")->valuestring;
            info.tempMax = cJSON_GetObjectItem(obj,"tempMax")->valueint;
            info.tempMin = cJSON_GetObjectItem(obj,"tempMin")->valueint;
            info.humidity = cJSON_GetObjectItem(obj,"humidity")->valueint;
            info.precip = cJSON_GetObjectItem(obj,"precip")->valuedouble;
            break;
        }
    }

    if(!strcmp(info.date,"2023-7-6")){
        printf("解析7月6日天气数据成功:\n");
        printf("时间:%s\n温度:%d度-%d度\n"\
               "天气:%s\n降水:%0.1fmm\n"\
               "湿度:%d%%\n",info.date,info.tempMax,info.tempMin,info.text,info.precip,info.humidity);
        puts("--------------------------------");
    }else{
        printf("解析7月6日天气数据失败\n");
    }

    cJSON_Delete(jsonList);

    return 0;
}

终端打印结果

封装的json如下:
-------------------------------
{
        "code": 200,
        "time": "2023-7-1T16:35+08:00",
        "daily":        [{
                        "date": "2023-7-4",
                        "tempMax":      36,
                        "tempMin":      27,
                        "humidity":     85,
                        "precip":       0,
                        "text": "阴"
                }, {
                        "date": "2023-7-5",
                        "tempMax":      31,
                        "tempMin":      27,
                        "humidity":     85,
                        "precip":       0,
                        "text": "阴"
                }, {
                        "date": "2023-7-6",
                        "tempMax":      32,
                        "tempMin":      28,
                        "humidity":     80,
                        "precip":       12.6,
                        "text": "中雨"
                }]
}
-------------------------------
无格式的JSON串:{"code":200,"time":"2023-7-1T16:35+08:00","daily":[{"date":"2023-7-4","tempMax":36,"tempMin":27,"humidity":85,"precip":0,"text":"阴"},{"date":"2023-7-5","tempMax":31,"tempMin":27,"humidity":85,"precip":0,"text":"阴"},{"date":"2023-7-6","tempMax":32,"tempMin":28,"humidity":80,"precip":12.6,"text":"中雨"}]}
-------------------------------
解析76日天气数据成功:
时间:2023-7-6
温度:32-28天气:中雨
降水:12.6mm
湿度:80%
--------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

money的大雨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值