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;
}



### 回答1: cjson 是一个用 C 语言编写的轻量级 JSON 库,它可以用于解析和生成 JSON 数据。它的特点是代码简单易懂、支持多种数据类型、解析速度快,因此在嵌入式系统和物联网设备开发中,cjson 是一种被广泛采用的 JSON 库。而 VS2019 是微软发布的一款集成开发环境,它支持多种编程语言的开发,包括 C++、C#、Java 等等。VS2019 提供了强大的调试功能、智能提示和自动完成等工具,大大提高了开发效率。 在使用 cjson 开发 JSON 应用时,我们可以利用 VS2019 提供的调试功能进行代码调试和错误追踪。在 VS2019 中可以轻松地设置断点,查看变量的值、内存使用情况等信息,方便我们快速定位错误。同时,VS2019 还提供了丰富的插件和扩展,可以进一步增强我们的开发能力,如 GitHub 插件、Node.js 工具、Docker 工具等等。 总之,cjson 和 VS2019 都是非常重要的开发工具,它们相辅相成,可以帮助我们快速开发高效可靠的 JSON 应用程序。 ### 回答2: cjson是一个轻量级的JSON解析和生成库,它可用于C、C++和其他语言。cjson提供了一组简单的API,以帮助用户在其应用程序中解析JSON字符串并构建JSON对象,还可以将JSON对象序列化为JSON字符串。 VS2019是微软公司发布的最新版本的Visual Studio开发环境,在软件开发中广泛使用。VS2019包括了许多新的功能和改进,例如代码重构、代码审查、代码片段、测试和调试工具等等。 在使用cjson库进行软件开发时,可以使用VS2019来开发和调试代码。VS2019拥有强大的调试工具,可以帮助开发人员快速和精准地发现和解决代码中的bug,从而提高软件的稳定性和可靠性。此外,VS2019还提供了许多代码编辑和调试功能,如智能代码提示、自动完成、代码重构、断点调试等等,可以帮助开发人员更加高效地完成开发任务。 总之,cjson库和VS2019是两个非常强大的工具,它们可以帮助开发人员轻松地解析和生成JSON数据,并提供各种高效的开发和调试工具。如果您正在使用cjson库进行软件开发,同时也使用VS2019,您将获得更高的生产力和更好的开发体验。 ### 回答3: CJSON是一种用于解析和生成JSON数据的C语言库。VS2019是微软公司推出的最新的集成开发环境。二者在功能和领域上没有直接联系,但是可以一起使用。 以CJSON和VS2019的使用为例,我们可以通过在VS2019中创建一个C语言项目,然后将CJSON库引入,并在代码中使用CJSON库提供的API来解析和生成JSON数据。 在使用CJSON和VS2019的过程中,需要注意CJSON库的使用方式和API使用文档,以确保正确使用和避免错误。同时,在VS2019中也需要注意编译选项和链接选项的配置,以确保程序可以正确地链接和运行。 总的来说,CJSON和VS2019是完全不同的工具和领域,但是它们可以一起使用,以实现特定的功能和应用场景。需要根据具体的需求来选择和使用合适的工具和技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值