一个功能比较齐全的cjson demo程序


/*  编译的时候需要添加数学链接库  -lm */
#include
#include
#include
#include
#include "cJSON.h"


static void print_cjson_obj_value(const cJSON * obj)
{
    if (!obj) {
        printf("NULL object!\n");
    }

    switch (obj->type) {
        case cJSON_False:
            printf("%s: false\n", obj->string);
            break;
        case cJSON_True:
            printf("%s: true\n", obj->string);
            break;
        case cJSON_NULL:
            printf("%s: cJSON_NULL\n", obj->string);
            break;
        case cJSON_Number:
            printf("%s: %d, %f\n",
                    obj->string, obj->valueint, obj->valuedouble);
            break;
        case cJSON_String:
            printf("%s: %s\n",
                    obj->string, obj->valuestring);
            break;
        case cJSON_Array:
            printf("%s: cJSON_Array\n", obj->string);
            break;
        case cJSON_Object:
            printf("%s: cJSON_Object\n", obj->string);
            break;
        default:
            printf("unknown type\n");
    }
}

/* *
 * 字符串转换成json对象
 */
int test_parse_json_string_to_object()
{
#define MY_JSON_STRING    \
    "{\"name\": \"Jack (\\\"Bee\\\") Nimble\", \
        \"format\": {                     \
            \"type\":      \"rect\", \
            \"width\":     1920,     \
            \"interlace\": true, \
            \"height\": 123.1 \
        },                                 \
        \"brother\": [ \
            \"Lea\",                     \
            \"Boo\"                         \
        ]                                 \
    }"

    /* 1. 解析,打印
     (1) cJSON_Parse解析字符串为json对象
     (2) cJSON_Print将json对象打包成字符串,使用之后需要释放字符串空间
    */
    printf("(1) parse, print\n");
    cJSON * cj_root = cJSON_Parse(MY_JSON_STRING);
    const char * cj_str = cJSON_Print(cj_root);
    printf("%s\n\n", cj_str);
    free(cj_str);

    /* 2. 获取对象
          (1) 如果获取的对象不存在,cJSON_GetObjectItem返回为空
          (2) cJSON_GetObjectItem只能获得当前对象的元素,不能获取前对象的元素中的对象
              例如
                   cJSON_GetObjectItem(cj_root,"format");不为空
                   cJSON_GetObjectItem(cj_root,"type");为空
          (3) 判断对象是否存在不使用cJSON_HasObjectItem(),直接判断cJSON_GetObjectItem()返回的指针是否为空
    */
    printf("(2) get object\n");
    cJSON * format = cJSON_GetObjectItem(cj_root, "format");
    cJSON * brother = cJSON_GetObjectItem(cj_root, "brother");
    cJSON * type = cJSON_GetObjectItem(cj_root, "type");
    printf("format [%p]\n", format);
    printf("brother [%p]\n", brother);
    printf("type [%p]\n", type);

    /* 3. 获取对象的值
          (1) 每个对象是由cJSON结构体组成
     (2) cJSON_Number包括整形和浮点型
     (3) 打印数组对象的值先判断数组长度,再打印。或者使用cJSON_ArrayForEach宏,后一个遍历速度更快
     (4) json使用完之后需要释放其空间
    */

    printf("\n(3) get object value\n");
    print_cjson_obj_value(cJSON_GetObjectItem(cj_root, "name"));
    print_cjson_obj_value(cJSON_GetObjectItem(format, "type"));
    print_cjson_obj_value(cJSON_GetObjectItem(format, "width"));
    print_cjson_obj_value(cJSON_GetObjectItem(format, "interlace"));
    print_cjson_obj_value(cJSON_GetObjectItem(format, "height"));

#if 0
    int size = cJSON_GetArraySize(brother);
    for (int i = 0; i < size; i++) {
        print_cjson_obj_value(cJSON_GetArrayItem(brother, i));
    }
#else
    cJSON * pos = NULL;
    cJSON_ArrayForEach(pos, brother) {
        print_cjson_obj_value(pos);
    }
#endif

    /* *
     * cjson使用完成之后需要释放空间
     */
    cJSON_Delete(cj_root);

#undef MY_JSON_STRING
}

/* *
 * json对象转化成字符串
 */
int test_pack_json_object_to_string()
{

    /*
     (1) 创建json对像,要先使用cJSON_CreateObject()创建一个根对象
     (2) 在使用cJSON_AddItemToObject()添加各种对象到根对象中。也可以直接使用头文件提供的宏来添加对象和值,如下
         cJSON_AddNullToObject(object,name)
        cJSON_AddTrueToObject(object,name)
        cJSON_AddFalseToObject(object,name)
        cJSON_AddBoolToObject(object,name,b)
        cJSON_AddNumberToObject(object,name,n)
        cJSON_AddStringToObject(object,name,s)
    */

    cJSON * root = NULL;
    cJSON * format = NULL;
    cJSON * brother = NULL;
    root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "name", "Jack (\"Bee\") Nimble");
    cJSON_AddItemToObject(root, "format", format=cJSON_CreateObject());
    cJSON_AddItemToObject(root, "brother", brother=cJSON_CreateArray());

    /* 普通对象中插入对象和值 */
    {
        cJSON_AddStringToObject(format, "type", "rect");
        cJSON_AddFalseToObject(format, "interlace");
        cJSON_AddNumberToObject(format, "width", 1920);
        cJSON_AddNumberToObject(format, "height", 1920.11);
        cJSON_AddBoolToObject(format, "flag", 1);
    }

    /* 数组中插入对象和值 */
    {
        cJSON_AddItemToArray(brother,cJSON_CreateString("Lea"));
        cJSON_AddItemToArray(brother,cJSON_CreateString("Boo"));
    }

    const char * cj_str = cJSON_Print(root);
    printf("%s\n\n", cj_str);
    free(cj_str);

    /* *
     * cjson使用完成之后需要释放空间
     */
    cJSON_Delete(root);
}

void print_cjson_string(const char * describe, const char *cj_str)
{
    printf("%s\n%s\n\n", describe, cj_str);
    free(cj_str);
}

/* *
 * 使用cjson提供的其它接口操作,都在cJSON.h中
 */
int test_cjson_operation()
{
#define MY_JSON_STRING    \
        "{\"name\": \"Lee\"}"

    /* *
     (1) cJSON_PrintUnformatted打印出的json字符串是紧凑的不用换行,适合传输json字符串时使用
     (2) cJSON_PrintBuffered可以事先指定分配一个缓冲区,如果足够大,则可以节省不断重新分配空间的时间;
         如果指定缓冲区过小,则与cJSON_Print和cJSON_PrintUnformatted性能能相同。
     (3) cJSON_PrintPreallocated可以将json字符串填入给定的缓冲区,并指定缓冲区大小。
         成功返回1,失败返回0。除了这个打印json字符串的函数,以上的函数在生成json字符串时若空间不足,
         都会重新分配一次空间。
     */
    cJSON * root = cJSON_Parse(MY_JSON_STRING);
    print_cjson_string("(1) cJSON_PrintUnformatted",
                 cJSON_PrintUnformatted(root));
    print_cjson_string("(2) cJSON_PrintBuffered",
                 cJSON_PrintBuffered(root, 1, 1));
    print_cjson_string("(3) cJSON_PrintBuffered",
                 cJSON_PrintBuffered(root, 1, 0));
#define BUF_LEN 1024
    char buf[BUF_LEN] = {0};
    if (0 == cJSON_PrintPreallocated(root, buf, BUF_LEN, 0)) {
        printf("(4) cJSON_PrintPreallocated\nfail\n\n");
    } else {
        printf("(4) cJSON_PrintPreallocated\n%s\n\n", buf);
    }
#undef BUF_LEN

    /* *
     (4) cJSON_GetErrorPtr可以获取字符串解析函数cJSON_Parse出错时的字符位置。
     如果解析没有错误,则返回NULL。
     */

    printf("(5) cJSON_GetErrorPtr\n");
    const cJSON * cj_tmp = cJSON_Parse("{\"haha\":12,, \"xixi\":34}");
    printf("[%s]\n\n", cJSON_GetErrorPtr());

    /* *
     (5) cJSON_CreateIntArray, cJSON_CreateFloatArray, cJSON_CreateDoubleArray和cJSON_CreateStringArray
     这4个函数可以直接将数组转换成json数组对象
     */
    int intarray[4] = {0, 1, 2, 3};
    cJSON_AddItemToObject(root, "intarray",cJSON_CreateIntArray(intarray, 4));
    print_cjson_string("(6) cJSON_CreateIntArray",cJSON_Print(root));

    /* *
     (6) cJSON_AddItemToObjectCS中的string参数是一个字符串常量,不需要为string分配空间。
         感觉没什么用。
     */
    const char * con_str = "haha";
    cJSON_AddItemToObjectCS(root, con_str, cJSON_CreateString("go"));
    print_cjson_string("(7) cJSON_AddItemToObjectCS",cJSON_Print(root));

    /* *
     (7) cJSON_AddItemReferenceToObject和cJSON_AddItemReferenceToArray
         将一个json对象引用到另一个json对象上,只拷贝了被引用对象的根节点,并不是复制所有节点到另一个json对象。
     */

    cJSON * n_root = cJSON_CreateObject();
    cJSON_AddItemReferenceToObject(n_root, "n_intarray",
                                 cJSON_GetObjectItem(root,"intarray"));
    print_cjson_string("(8) cJSON_AddItemReferenceToObject",cJSON_Print(n_root));

    /* *
     (8) cJSON_DetachItemFromArray, cJSON_DeleteItemFromArray, cJSON_DetachItemFromObject, cJSON_DeleteItemFromObject
         cJSON_DetachItemFromArray是从json数组对象中分离出来第n个节点,cJSON_DeleteItemFromArray是删除json数组对象的第n个节点
         cJSON_DetachItemFromObject是分离任意节点,cJSON_DeleteItemFromObject是删除任意节点
     */
    cJSON_DeleteItemFromArray(cJSON_GetObjectItem(root,"intarray"), 2);
    print_cjson_string("(9) cJSON_DeleteItemFromArray",cJSON_Print(root));

    /* *
     (9) cJSON_InsertItemInArray 插入节点到数组中
         cJSON_ReplaceItemInArray 替换数组中的第n个节点
         cJSON_ReplaceItemInObject 替换任意节点
     */
    cJSON_InsertItemInArray(cJSON_GetObjectItem(root,"intarray"),
                             2, cJSON_CreateNumber(2));
      cJSON_ReplaceItemInObject(root, "name", cJSON_CreateString("Bluce"));
       print_cjson_string("(10) cJSON_DeleteItemFromArray",cJSON_Print(root));

       /* *
     (10) cJSON_InsertItemInArray 插入节点到数组中
         cJSON_ReplaceItemInArray 替换数组中的第n个节点
         cJSON_ReplaceItemInObject 替换任意节点
     */
    cJSON_InsertItemInArray(cJSON_GetObjectItem(root,"intarray"),
                             2, cJSON_CreateNumber(2));
      cJSON_ReplaceItemInObject(root, "name", cJSON_CreateString("Bluce"));
       print_cjson_string("(11) cJSON_DeleteItemFromArray",cJSON_Print(root));

       /* *
     (11) cJSON_Duplicate recurse为1表示递归复制一个json对象。
     */
       cJSON * cj_duplicate = cJSON_Duplicate(root, 1);
    print_cjson_string("(12) cJSON_Duplicate",cJSON_Print(cj_duplicate));

       /* *
     (12) cJSON_ParseWithOpts
         该函数是cJSON_Parse的实现,但是它比cJSON_Parse更灵活。
         1.如果cJSON_Parse解析错误,必须调用cJSON_GetErrorPtr找到解析错误位置
         2.cJSON_Parse解析不严谨,如"{\"name\": \"Lee\"} }"这个字符串,后边多了一个大括号,但还是解析成功了。
         3.cJSON_ParseWithOpts的return_parse_end参数可以获取解析失败的位置,
          require_null_terminated参数为1会检查剩余未解析字符串是否是空字符串,
          若不为空字符串,则会释放内存,返回空。
          @所以因该使用cJSON_ParseWithOpts解析json对象
     */
    {
        printf("(13) cJSON_ParseWithOpts\n");
        char * end = NULL;
     cJSON * cj_ParseWithOpts = cJSON_ParseWithOpts("{\"name\": \"Lee\"} }", &end, 1);
     if (cj_ParseWithOpts) {
            printf("%s\n\n", cJSON_Print(cj_ParseWithOpts));
     } else {
            printf("[%s]\n\n", end);
     }
    }

    {
        printf("(14) cJSON_Parse\n");
        char * end = NULL;
     cJSON * cj_ParseWithOpts = cJSON_Parse("{\"name\": \"Lee\"} }");
     if (cj_ParseWithOpts) {
            printf("%s\n\n", cJSON_Print(cj_ParseWithOpts));
     } else {
            printf("[%s]\n\n", end);
     }
    }

    /* *
     (12) cJSON_SetIntValue和cJSON_SetNumberValue相同,
          既可以设置整形值,也可以设置double类型值。
     */
    printf("(15) cJSON_SetIntValue\n");
    cJSON * int_cj = cJSON_CreateNumber(1);
    printf("%s\n", cJSON_Print(int_cj));
    cJSON_SetIntValue(int_cj, 1.1);
    printf("%s\n\n", cJSON_Print(int_cj));

    cJSON_Delete(root);
}


int main()
{
    //将json字符串解析成json对象
    printf("<< test_parse_json_string_to_object >>\n");
    test_parse_json_string_to_object();

    //将生成json对象,并将json对象组成字符串
    printf("\n<< test_pack_json_object_to_string >>\n");
    test_pack_json_object_to_string();

    //其它一些json接口测试
    printf("<< test_cjson_operation >>\n");
    test_cjson_operation();
    return 0;
}

结果:

[root@192 cJSON]# ./main
<< test_parse_json_string_to_object >>
(1) parse, print
{
        "name": "Jack (\"Bee\") Nimble",
        "format": {
                "type": "rect",
                "width": 1920,
                "interlace": true,
                "height": 123.100000
        },
        "brother": ["Lea", "Boo"]
}

(2) get object
format [0x9a87080]
brother [0x9a871a8]
type [(nil)]

(3) get object value
name: Jack ("Bee") Nimble
type: rect
width: 1920, 1920.000000
interlace: true
height: 123, 123.100000
(null): Lea
(null): Boo

<< test_pack_json_object_to_string >>
{
        "name": "Jack (\"Bee\") Nimble",
        "format": {
                "type": "rect",
                "interlace": false,
                "width": 1920,
                "height": 1920.110000,
                "flag": true
        },
        "brother": ["Lea", "Boo"]
}

<< test_cjson_operation >>
(1) cJSON_PrintUnformatted
{"name":"Lee"}

(2) cJSON_PrintBuffered
{
        "name": "Lee"
}

(3) cJSON_PrintBuffered
{"name":"Lee"}

(4) cJSON_PrintPreallocated
{"name":"Lee"}

(5) cJSON_GetErrorPtr
[, "xixi":34}]

(6) cJSON_CreateIntArray
{
        "name": "Lee",
        "intarray": [0, 1, 2, 3]
}

(7) cJSON_AddItemToObjectCS
{
        "name": "Lee",
        "intarray": [0, 1, 2, 3],
        "haha": "go"
}

(8) cJSON_AddItemReferenceToObject
{
        "n_intarray": [0, 1, 2, 3]
}

(9) cJSON_DeleteItemFromArray
{
        "name": "Lee",
        "intarray": [0, 1, 3],
        "haha": "go"
}

(10) cJSON_DeleteItemFromArray
{
        "name": "Bluce",
        "intarray": [0, 1, 2, 3],
        "haha": "go"
}

(11) cJSON_DeleteItemFromArray
{
        "name": "Bluce",
        "intarray": [0, 1, 2, 2, 3],
        "haha": "go"
}

(12) cJSON_Duplicate
{
        "name": "Bluce",
        "intarray": [0, 1, 2, 2, 3],
        "haha": "go"
}

(13) cJSON_ParseWithOpts
[}]

(14) cJSON_Parse
{
        "name": "Lee"
}

(15) cJSON_SetIntValue
1
1.100000

你可能感兴趣的:(基础编程方法)