Sword cjson库函数使用

cJSON介绍

a.结构体cJSON

typedef struct cJSON {
    struct cJSON *next,*prev;    /* next是获取下一个元素数据,prev是获取前一个元素数据 */
    struct cJSON *child;        /* 获取第一个元素数据,当需要获取下一个时,就得使用next了. */

    int type;                    /* 当前的json类型对象、数组、字符串、数字、null、true、false等 */

    char *valuestring;            /* 字符串值, if type==cJSON_String */
    int valueint;                /* 整形类型值, if type==cJSON_Number */
    double valuedouble;            /* 浮点数类型值, if type==cJSON_Number */

    char *string;                /* 这个是键 */
} cJSON;

b.type类型,与下面的宏进行判断

/* cJSON Types: */
#define cJSON_False 0        // true
#define cJSON_True 1        // false
#define cJSON_NULL 2        // NULL
#define cJSON_Number 3        // 数字
#define cJSON_String 4        // 字符串
#define cJSON_Array 5        // 数组
#define cJSON_Object 6        // 对象

c.字符串生成cjson指针的函数,使用后需要调用cJSON_Delete进行释放

extern cJSON *cJSON_Parse(const char *value);

// 释放cJSON_Parse返回的指针
extern void   cJSON_Delete(cJSON *c);

 d.cjson指针指针生成字符串的函数

// 这个生成的字符串有做格式调整
extern char  *cJSON_Print(cJSON *item);
// 这个没有作格式调整,就是一行字符串显示
extern char  *cJSON_PrintUnformatted(cJSON *item);
// 需要释放它们返回的指针内存,否则会造成内存泄漏。

 

/* cjson库的使用 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "cJSON.h"

/*
说明:
    组装成json效率并不高,并不推荐json,字符串远比json快,但是字符串表示不了对象,protobuf虽然快,但是依赖于第三方库,很棘手
*/

//数据解析
int testPause(const char* pcJson)
{
    cJSON* pstRoot = NULL;
    cJSON* pstNode = NULL;
    cJSON* pstFeat = NULL;
    cJSON* pstArray = NULL;
    cJSON* pstAudio = NULL;
    cJSON* pstRole = NULL;
    cJSON* pstTmp = NULL;
    int arraySize = 0;
    int i = 0, j = 0;
    int featSize = 0;
    char* p = NULL;

    if (NULL == pcJson)
    {
        return -1;
    }

    //解析json字符串
    pstRoot = cJSON_Parse(pcJson);
    if (NULL == pstRoot)
    {
        return -1;
    }

    do
    {
        //获取json对象
        pstAudio = cJSON_GetObjectItem(pstRoot, "audio");
        /*
        注意点:
            注意cjson库是如何判断字符串的

            if (pstAudio && strlen(pstAudio->valuestring))

            这种判断是不正确的,当pstAudio不是一个字符串类型时,pstAudio->valuestring实际上就是NULL,strlen(NULL)会直接导致崩溃

        */
        if (NULL == pstAudio || cJSON_String != pstAudio->type)
        {
            printf("--no audio info .---\n");
            break;
        }
        

        //获取字符串型json对象的值
        printf("====audio info %s=======\n", pstAudio->valuestring);

        pstArray = cJSON_GetObjectItem(pstRoot, "array");
        if (NULL == pstArray)
        {
            printf("--no array info .---\n");
            break;
        }

        //提取json数组
        //1.获取数组长度
        arraySize = cJSON_GetArraySize(pstArray);
        if (0 == arraySize)
        {
            printf("--no array info .---\n");
            break;
        }

        for (i = 0; i < arraySize; i++)
        {
            pstNode = cJSON_GetArrayItem(pstArray, i);
            if (pstNode)
            {
                //获取角色信息
                pstRole = cJSON_GetObjectItem(pstNode, "role");
                if (NULL == pstRole || cJSON_Number != pstNode->type)
                {
                    printf("--no role info .---\n");
                    break;
                }

                // 修改角色信息

                cJSON_ReplaceItemInObject(pstNode, "role", cJSON_CreateNumber(3));

                //获取声纹信息
                pstFeat = cJSON_GetObjectItem(pstNode, "feat");
                if (NULL == pstFeat)
                {
                    printf("--no feat info .---\n");
                    break;
                }

                //获取声纹长度
                featSize = cJSON_GetArraySize(pstFeat);
                if (0 == featSize)
                {
                    printf("--no feat size info .---\n");
                    break;
                }
                for (j = 0; j < featSize; j++)
                {
                    pstTmp = cJSON_GetArrayItem(pstFeat, j);
                    printf("==feat[%lf]==\n", pstTmp->valuedouble);
                }
            }
        }

        p = cJSON_Print(pstRoot);
        printf("[ testPause ] |%s|\n", p);

    } while (0);

    // 释放资源
    if (pstRoot)
    {
        cJSON_Delete(pstRoot);
        pstRoot = NULL;
    }

    if (p)
    {
        free(p);
        p = NULL;
    }

    return 0;
}

//数据组装
char* testAssemble(void)
{
    cJSON* pstRoot = NULL;
    cJSON* pstNode = NULL;
    cJSON* pstFeat = NULL;
    cJSON* pstArray = NULL;
    float aFeat[10] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 0.0f };
    char* pOutput = NULL;

    //创建普通json对象
    pstRoot = cJSON_CreateObject();
    assert(pstRoot);

    pstNode = cJSON_CreateObject();
    assert(pstNode);

    //创建float数组类型json对象
    pstFeat = cJSON_CreateFloatArray(aFeat, 10);
    assert(pstFeat);

    cJSON_AddNumberToObject(pstNode, "role", 1);
    cJSON_AddItemToObject(pstNode, "feat", pstFeat);

    //创建一个json对象数组
    pstArray = cJSON_CreateArray();
    assert(pstArray);

    //将一个json对象加入到json数组中
    cJSON_AddItemToArray(pstArray, pstNode);

    //布尔值添加
    cJSON_AddStringToObject(pstRoot, "audio", "test.wav");
    cJSON_AddItemToObject(pstRoot, "array", pstArray);

    //输出json字符串(内存需要自己释放)
    pOutput = cJSON_Print(pstRoot);

    // 释放资源
    if (pstRoot)
    {
        cJSON_Delete(pstRoot);
        pstRoot = NULL;
    }

    return pOutput;

}

int main()
{
    char* pcJson = NULL;

    pcJson = testAssemble();
    if (NULL == pcJson)
    {
        printf("----[testAssemble]-----failed-----\n");
        return -1;
    }

    //打印数据
    printf("|%s|\n", pcJson);

    printf("\n");

    //解析json
    testPause(pcJson);

    //释放资源
    if (pcJson)
    {
        free(pcJson);
        pcJson = NULL;
    }

    printf("-----ok------\n");

    getchar();

    return 0;
}

 

posted on 2019-06-30 07:11  寒魔影  阅读(531)  评论(0编辑  收藏  举报

导航