cJSON例说

“JSON”的全称是“JavaScriptObject Notation”,即JavaScript对象符号,是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。JSON采用与编程语言无关的文本格式,但是也使用了类C语言(包括C、C++、C#、Java、JavaScript、Python等)的习惯,这些特性使JSON成为理想的数据交换格式。

 

JSON建构于两种结构

(1)“名称/值”对的集合。不同的语言中,其被理解为对象(“object”)、纪录(“record”)、结构(“struct”)、字典(“dictionary”)、哈希表(“hash table”)、有键列表(“keyed list”)或者关联数组(“associativearray”)。

(2)值的有序列表。在大部分语言中,其被理解为数组(“array”)。

 

简单理解,JSON的定义由以下四句话就全部定义了。

  • 并列的数据之间用逗号(”,”)分隔。
  • 映射用冒号(”:”)表示。
  • 并列数据的集合(数组)用方括号("[]")表示。
  • 映射的集合(对象)用大括号(”{}”)表示。

 

cJSON数据结构定义

/* The cJSON structure: */

typedef struct cJSON {

       struct cJSON *next,*prev;            /* 如果该Json结构在数组中,则它的前后节点*/

       struct cJSON *child;                    /* 如果存在子对象,其第一个子对象*/

       int type;                              /* 键的类型Json对象的类型,可以是字符串,整型或者浮点型*/

       char *valuestring;                 /* 字符串The item's string, if type==cJSON_String*/

       int valueint;                         /* 整型The item's number, if type==cJSON_Number*/

       double valuedouble;                    /* 浮点型The item's number, if type==cJSON_Number*/

       char *string;                        /* “键”的名称Json对象的名字*/

} cJSON;


Json对象的类型

/* cJSON Types: */

#define cJSON_False 0

#define cJSON_True 1

#define cJSON_NULL 2

#define cJSON_Number 3

#define cJSON_String 4

#define cJSON_Array 5

#define cJSON_Object 6

 

cJson中的基本函数API

CJSON在内存中的存储方式是用链表进行存储的,所以在进行操作的时候,我们可见的部分全部是用指针进行操作的。

函数功能

解析函数

函数定义

extern cJSON *cJSON_Parse(const char *value)

函数说明

传入一个字符串,并按照cJSON结构体的结构序列化整个数据包,可以通过if (!json)来判断解析是否出错,如果出错,可以通过printf("Error before: [%s]\n",cJSON_GetErrorPtr())打印出错位置。使用该函数会通过malloc函数在内存中开辟一个空间,使用完成需要手动释放,调用cJSON_Delete()。

 

函数功能

打印cJSON

函数定义

extern char  *cJSON_Print(cJSON *item)

函数说明

传入一个cJSON,将会以排好版的格式打印JSON。完成后需要释放分配的内存空间,调用free()。

 

函数功能

释放cJSON内存空间

函数定义

extern void cJSON_Delete(cJSON *c)

函数说明

获得了一个cJSON,当使用完了之后要删除,因为返回的cJSON是通过malloc的方式分配的,如果用完不及时释放会造成内存泄露。

 

函数功能

获取cJSON大小

函数定义

extern int cJSON_GetArraySize(cJSON *array)

函数说明

返回数组或对象中的大小,只要该对象下包括其他对象,各对象一般以“,”分隔。

 

函数功能

以index的方式获取cJSON数组或对象相应的项

函数定义

extern cJSON *cJSON_GetArrayItem(cJSON *array,int item)

函数说明

返回数组或对象中相应index的项,找不到会返回NULL。

 

函数功能

以名称的方式获取cJSON数组或对象相应的项

函数定义

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

函数说明

获取当前cJSON对象下有名字的cJSON对象,找不到会返回NULL。

 

函数功能

创建cJSON对象

函数定义

extern cJSON *cJSON_CreateObject(void)

函数说明

创建cJSON对象项,从内存中分配空间,内存不够返回NULL。然后通过cJSON_AddItemToObject将分配的空间增加到其他空间上,所以不需要重复删除内存空间。



函数功能

添加一个对象项到一个指定的对象上

函数定义

extern void   cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)

函数说明

一般创建子对象是需要用到,将子对象添加到父对象上。


例说

以JSON中国网站的例子,测试代码



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

char *makeJson()
{
    cJSON * pJsonRoot = cJSON_CreateObject();
    if(NULL == pJsonRoot)
    {
        // create object faild, exit
        return NULL;
    }
    cJSON_AddStringToObject(pJsonRoot, "name", "JSON中国");
    cJSON_AddStringToObject(pJsonRoot, "url", "http://www.json.org.cn");
    cJSON_AddNumberToObject(pJsonRoot, "page", 88);
    cJSON_AddBoolToObject(pJsonRoot, "isNonProfit", 1);

    cJSON * pJsonSub = cJSON_CreateObject();
    if(NULL == pJsonSub)
    {
        // create object faild, exit
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddItemToObject(pJsonRoot, "address", pJsonSub);
    cJSON_AddStringToObject(pJsonSub, "street", "浙大路38号.");
    cJSON_AddStringToObject(pJsonSub, "city", "浙江杭州");
    cJSON_AddStringToObject(pJsonSub, "country", "中国");

    pJsonSub =  cJSON_CreateArray();
    if(NULL == pJsonSub)
    {
        // create object faild, exit
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddItemToObject(pJsonRoot, "links", pJsonSub);

    cJSON * pJsonSubSub;
    pJsonSubSub = cJSON_CreateObject();
    if(NULL == pJsonSubSub)
    {
        // create object faild, exit
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddItemToArray(pJsonSub, pJsonSubSub);
    cJSON_AddStringToObject(pJsonSubSub, "name", "Google");
    cJSON_AddStringToObject(pJsonSubSub, "url", "http://www.google.com");
    pJsonSubSub = cJSON_CreateObject();
    if(NULL == pJsonSubSub)
    {
        // create object faild, exit
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddItemToArray(pJsonSub, pJsonSubSub);
    cJSON_AddStringToObject(pJsonSubSub, "name", "Baidu");
    cJSON_AddStringToObject(pJsonSubSub, "url", "http://www.baidu.com");
    pJsonSubSub = cJSON_CreateObject();
    if(NULL == pJsonSubSub)
    {
        // create object faild, exit
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddItemToArray(pJsonSub, pJsonSubSub);
    cJSON_AddStringToObject(pJsonSubSub, "name", "SoSo");
    cJSON_AddStringToObject(pJsonSubSub, "url", "http://www.SoSo.com");

    //char * p = cJSON_Print(pJsonRoot);
    char * p = cJSON_PrintUnformatted(pJsonRoot); //free(p);
    if(NULL == p)
    {
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    //convert json list to string faild, exit
    //because sub json pJsonSubSub han been add to pJsonRoot, so just delete pJsonRoot,
    //if you also delete pJsonSubSub, it will coredump, and error is : double free
    cJSON_Delete(pJsonRoot);
    return p;
}

char *parseJson(char *pMsg)
{
    int i;
    if(NULL == pMsg)
    {
        return NULL;
    }
    cJSON *pJsonRoot = cJSON_Parse(pMsg);
    if(NULL == pJsonRoot)
    {
        // parse faild, return
        return NULL;
    }
    // get string from json
    cJSON * pJsonSub = cJSON_GetObjectItem(pJsonRoot, "name");
    if(NULL == pJsonSub)
    {
        //get object named "name" faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("name : %s\n", pJsonSub->valuestring);
    cJSON_ReplaceItemInObject(pJsonRoot,"name",cJSON_CreateString("JSON中国 1"));//修改json的数据
    // get string from json
    pJsonSub = cJSON_GetObjectItem(pJsonRoot, "url");
    if(NULL == pJsonSub)
    {
        //get object named "url" faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("url : %s\n", pJsonSub->valuestring);
    cJSON_ReplaceItemInObject(pJsonRoot,"url",cJSON_CreateString("http://www.json.org.cn 1"));//修改json的数据
    // get number from json
    pJsonSub = cJSON_GetObjectItem(pJsonRoot, "page");
    if(NULL == pJsonSub)
    {
        //get number from "page" faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("page : %d\n", pJsonSub->valueint);
    cJSON_ReplaceItemInObject(pJsonRoot,"page",cJSON_CreateNumber(88+1));//修改json的数据
    // get bool from json
    pJsonSub = cJSON_GetObjectItem(pJsonRoot, "isNonProfit");
    if(NULL == pJsonSub)
    {
        // get bool from "isNonProfit" faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("isNonProfit : %d\n", pJsonSub->valueint);
    cJSON_ReplaceItemInObject(pJsonRoot,"isNonProfit",cJSON_CreateBool(0));//修改json的数据
    // get sub object
    pJsonSub = cJSON_GetObjectItem(pJsonRoot, "address");
    if(NULL == pJsonSub)
    {
        // get sub object faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    // get sub sub object
    cJSON *pJsonSubSub = cJSON_GetObjectItem(pJsonSub, "street");
    if(NULL == pJsonSubSub)
    {
        // get object from subject object faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("address->street : %s\n", pJsonSubSub->valuestring);
    cJSON_ReplaceItemInObject(pJsonSub,"street",cJSON_CreateString("浙大路38号. 1"));//修改json的数据
    pJsonSubSub = cJSON_GetObjectItem(pJsonSub, "city");
    if(NULL == pJsonSubSub)
    {
        // get object from subject object faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("address->city : %s\n", pJsonSubSub->valuestring);
    cJSON_ReplaceItemInObject(pJsonSub,"city",cJSON_CreateString("浙江杭州 1"));//修改json的数据
    pJsonSubSub = cJSON_GetObjectItem(pJsonSub, "country");
    if(NULL == pJsonSubSub)
    {
        // get object from subject object faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    printf("address->country : %s\n", pJsonSubSub->valuestring);
    cJSON_ReplaceItemInObject(pJsonSub,"country",cJSON_CreateString("中国 1"));//修改json的数据
    pJsonSub = cJSON_GetObjectItem(pJsonRoot, "links");
    if(NULL == pJsonSub)
    {
        // get sub object faild
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    for (i = 0; i < cJSON_GetArraySize(pJsonSub); i++)
    {

        cJSON *pJsonSubArry = cJSON_GetArrayItem(pJsonSub, i);
        if(NULL == pJsonSubArry)
        {
            // get sub object faild
            cJSON_Delete(pJsonRoot);
            return NULL;
        }
        pJsonSubSub = cJSON_GetObjectItem(pJsonSubArry, "name");
        if(NULL == pJsonSub)
        {
            // get object from subject object faild
            cJSON_Delete(pJsonRoot);
            return NULL;
        }
        printf("links[%d]->name : %s\n", i, pJsonSubSub->valuestring);
        cJSON_ReplaceItemInObject(pJsonSubArry,"name",cJSON_CreateString("name 1"));//修改json的数据
        pJsonSubSub = cJSON_GetObjectItem(pJsonSubArry, "url");
        if(NULL == pJsonSubSub)
        {
            // get object from subject object faild
            cJSON_Delete(pJsonRoot);
            return NULL;
        }
        printf("links[%d]->url : %s\n", i, pJsonSubSub->valuestring);
        cJSON_ReplaceItemInObject(pJsonSubArry,"url",cJSON_CreateString("url 1"));//修改json的数据
    }
    char * p = cJSON_Print(pJsonRoot);
    //char * p = cJSON_PrintUnformatted(pJsonRoot); //free(p);
    if(NULL == p)
    {
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    //Call cJSON_Delete when finished.
    cJSON_Delete(pJsonRoot);
    return p;
}

int main()
{
    FILE *fp = fopen("test.txt", "w");
    if (fp == NULL)
        exit(1);

    printf("===============================\r\n\r\n");
    printf("===============================\r\n\r\n");
    char * p = makeJson();
    if(NULL == p)
    {
        exit(1);
    }
    printf("%s\n", p);
    printf("===============================\r\n\r\n");
    printf("===============================\r\n\r\n");
    p = parseJson(p);
    printf("===============================\r\n\r\n");
    printf("===============================\r\n\r\n");
    printf("%s\n", p);
    fputs(p, fp);
    free(p);//千万不要忘记释放内存呀,cJSON_Print()函数或者cJSON_PrintUnformatted()产生的内存,使用free(char *)进行释放
    fclose(fp);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值