cjson 对象是json数组型结构体_cJSON使用简介

本文详细介绍了如何使用cJSON库解析JSON字符串到对象,并展示了如何获取JSON对象的值,创建JSON对象并转化为字符串。通过示例代码演示了cJSON的主要操作,包括解析、打印、获取对象和值、添加和删除JSON元素等。

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

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值