当前位置: 首页 > 工具软件 > cjson > 使用案例 >

cJSON使用

燕飞文
2023-12-01

  cJSON是一个开源的跨平台的用C语言解析和生成json格式数据的库,项目地址为cJSON项目地址。使用时只需要复制 cJSON.c 和 cJSON.h 到项目中即可使用,使用示例可以参考官方的 test.c,也可以参考下面我写的示例教程。
  说明:下面的代码均已验证,且不寻在内存泄漏的问题,有什么使用问题,欢迎一起交流。

1 简单的JSON对象示例

1.1 创建、修改和打印

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

int main()
{
    cJSON *root = NULL, *person = NULL;
    char *str_print = NULL;

    /* 创建cJSON对象 */
    root = cJSON_CreateObject();    /* 创建一个cJSON对象,要用 cJSON_Delete 释放内存 */
    person = cJSON_CreateObject();  /* 创建子对象 */

    /* 添加json节点 */
    cJSON_AddItemToObject(root, "person", person);
    cJSON_AddStringToObject(person, "firstName", "Lebron");
    cJSON_AddStringToObject(person, "lastName", "James");
    cJSON_AddNumberToObject(person, "age", 36);
    cJSON_AddNumberToObject(person, "height", 206);
    cJSON_AddStringToObject(root, "team", "Lakers");

    /* 打印 */
    str_print = cJSON_Print(root);
    if(str_print != NULL)
    {
        printf("%s\n", str_print);
        cJSON_free(str_print);
        str_print = NULL;
    }

    /* 修改cJSON对象中的内容 */
    cJSON_ReplaceItemInObject(person, "firstName", cJSON_CreateString("Chris"));
    cJSON_ReplaceItemInObject(person, "lastName", cJSON_CreateString("Paul"));
    cJSON_ReplaceItemInObject(person, "age", cJSON_CreateNumber(36));
    cJSON_ReplaceItemInObject(person, "height", cJSON_CreateNumber(183));
    cJSON_ReplaceItemInObject(root, "team", cJSON_CreateString("sun"));

    /* 打印修改后的cJSON对象 */
    str_print = cJSON_Print(root);
    if(str_print != NULL)
    {
        printf("\n%s\n", str_print);
        cJSON_free(str_print);
        str_print = NULL;
    }

    /* 释放内存 */
    if(root != NULL)
        cJSON_Delete(root); // 防止内存泄露,会把下面所有的子节点都释放
	
	return 0;
}

  执行结果如下:

linux@linux-VirtualBox:~/myfiles/cJson$ gcc app.c cJSON.c -o app
linux@linux-VirtualBox:~/myfiles/cJson$ ./app
{
	"person":	{
		"firstName":	"Lebron",
		"lastName":	"James",
		"age":	36,
		"height":	206
	},
	"team":	"Lakers"
}

{
	"person":	{
		"firstName":	"Chris",
		"lastName":	"Paul",
		"age":	36,
		"height":	183
	},
	"team":	"sun"
}

1.2 解析JSON格式数据

  将上面创建的JSON格式的数据进行解析并输出,解析代码如下。在解析代码中设置的两个数字的类型分别是整数-和小数,在打印时分别以整数和小数进行打印,发现整数打印的结果将小数取整,数值定义的是整数时小数也能打印出从结果,相应的在代码30和31行。 type为cJSON定义的数据的类型,在 cJSON.h 中的88-97行定义。

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

int main()
{
    /* 定义要解析的JSON对象 */
    char *cJSON_str = "{                      \
	    \"person\":	{                         \
		\"firstName\":	\"Lebron\",           \
		\"lastName\":	\"James\",            \
		\"age\":	    36,                   \
		\"height\":	    203.5                 \
	    },                                    \
        \"team\": \"Lakers\"                  \
    }";

    /* 解析JSON对象 */
    cJSON *obj = cJSON_Parse(cJSON_str);
    cJSON *child = cJSON_GetObjectItem(obj, "person");  // 从根节点下找到子节点
    
    cJSON *firstName = cJSON_GetObjectItem(child, "firstName");  // 在子节点中找到对应的键
    cJSON *lastName = cJSON_GetObjectItem(child, "lastName");
    cJSON *age = cJSON_GetObjectItem(child, "age");
    cJSON *height = cJSON_GetObjectItem(child, "height");
    cJSON *team = cJSON_GetObjectItem(obj, "team");              // 在根节点中找到对应的键

    printf("firstName type: 0x%02x, content: %s, %d\n", firstName->type, firstName->valuestring, firstName->valueint);
    printf("lastName  type: 0x%02x, content: %s, %f\n", lastName->type,  lastName->valuestring,  lastName->valuedouble);
    printf("age       type: 0x%02x, content: %d, %f\n", age->type,       age->valueint,          age->valuedouble);
    printf("height    type: 0x%02x, content: %d, %f\n", height->type,    height->valueint,       height->valuedouble);
    printf("team      type: 0x%02x, content: %s, %d\n", team->type,      team->valuestring,      team->valueint);

    /* 释放空间 */
    if(obj != NULL)
        cJSON_Delete(obj);

    return 0;
}

  执行结果如下:

linux@linux-VirtualBox:~/myfiles/cJson$ gcc app.c cJSON.c -o app
linux@linux-VirtualBox:~/myfiles/cJson$ ./app
firstName type: 0x10, content: Lebron, 0
lastName  type: 0x10, content: James, 0.000000
age       type: 0x08, content: 36, 36.000000
height    type: 0x08, content: 203, 203.500000
team      type: 0x10, content: Lakers, 0

2 JSON数组

2.1 创建和打印

  了解了简单的JSON格式数据的创建,解析后接下来讲解一下JSON数组的创建示例,代码如下:

/*
 * @Description: 
 * @Version: 1.0
 * @Autor: Crystal
 * @Date: 2021-07-02 14:10:40
 * @LastEditors: Crystal
 * @LastEditTime: 2021-07-02 16:51:47
 */
#include <stdio.h>
#include "cJSON.h"

typedef struct{
    int id;
    char *name;
    int age;
    char *hobby;
}stu_t;

int main(void)
{
    int i;
    
    /* 定义学生信息结构体数组 */
    stu_t stu_info[3] = {
        {1, "xiaoming", 18, "basketball"},
        {2, "xiaolan",  17, "tennis"},
        {3, "xiaohong", 18, "piano"}
    };
    
    /* 创建JSON对象 */
    cJSON *root = cJSON_CreateObject();      // 创建根节点
    cJSON *students = cJSON_CreateObject();  // 创建 students 子节点
    cJSON_AddItemToObject(root, "students", students); // 将子节点添加到根节点中
    cJSON_AddNumberToObject(students, "total", 3);     // 在 students 子节点添加键值对 total   


    cJSON *arr_info;
    cJSON *stu_arr = cJSON_CreateArray();  // 创建数组
    cJSON_AddItemToObject(students, "student", stu_arr);   // 将数组添加到他的父节点中
    for(i=0; i<sizeof(stu_info)/sizeof(stu_info[0]); ++i)  // 循环给数组赋值
    {
        arr_info = cJSON_CreateObject();  // 创建对象
        cJSON_AddNumberToObject(arr_info, "id", stu_info[i].id);      // 给新创建的对象赋值
        cJSON_AddStringToObject(arr_info, "name", stu_info[i].name);  
        cJSON_AddNumberToObject(arr_info, "age", stu_info[i].age);
        cJSON_AddStringToObject(arr_info, "hobby", stu_info[i].hobby);
        cJSON_AddItemToArray(stu_arr, arr_info);                      // 将对象添加到数组中
    }

    
    cJSON_AddStringToObject(root, "grade", "senior three"); // 将 grade 添加到他的父节点中


    cJSON *subject = cJSON_CreateArray();   // 创建数组
    cJSON_AddItemToObject(root, "subject", subject);  // 将数组添加到他的父节点中
    cJSON_AddItemToArray(subject, cJSON_CreateString("Chinese"));   // 数组元素赋值
    cJSON_AddItemToArray(subject, cJSON_CreateString("math"));
    cJSON_AddItemToArray(subject, cJSON_CreateString("English"));
       
    /* 格式化打印创建的带数组的JSON对象 */
    char *str_print = cJSON_Print(root);
    if(str_print != NULL)
    {
        printf("%s\n", str_print);
        cJSON_free(str_print);
        str_print = NULL;
    }

    if(root != NULL)
        cJSON_Delete(root);

    return 0;
}

  执行结果如下:

linux@linux-VirtualBox:~/myfiles/cJson$ gcc app.c cJSON.c -o app
linux@linux-VirtualBox:~/myfiles/cJson$ ./app
{
	"students":	{
		"total":	3,
		"student":	[{
				"id":	1,
				"name":	"xiaoming",
				"age":	18,
				"hobby":	"basketball"
			}, {
				"id":	2,
				"name":	"xiaolan",
				"age":	17,
				"hobby":	"tennis"
			}, {
				"id":	3,
				"name":	"xiaohong",
				"age":	18,
				"hobby":	"piano"
			}]
	},
	"grade":	"senior three",
	"subject":	["Chinese", "math", "English"]
}

2.2 解析JSON数组

  将上面创建的JSON格式的数据进行解析并输出,解析代码如下。

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

int main(void)
{
    /* 要解析的json对象 */
    char *str_json = "                                          \
        {                                                       \
            \"students\" : {                                    \
                \"total\" : 3,                                  \
                \"student\" : [                                 \
                    {                                           \
                            \"id\" : 1,                         \
                            \"name\" : \"xiaoming\",            \
                            \"age\" : 18,                       \
                            \"hobby\" : \"basketball\"          \
                    },                                          \
                    {                                           \
                            \"id\" : 2,                         \
                            \"name\" : \"xiaolan\",             \
                            \"age\" : 17,                       \
                            \"hobby\" : \"tennis\"              \
                    },                                          \
                    {                                           \
                            \"id\" : 3,                         \
                            \"name\" : \"xiaohong\",            \
                            \"age\" : 18,                       \
                            \"hobby\" : \"piano\"               \
                    }                                           \
                ]                                               \
            },                                                  \
            \"grade\" : \"senior three\",                       \
            \"subject\": [\"Chinese\", \"math\", \"English\"]   \
        }                                                       \
    ";

    cJSON *root = cJSON_Parse(str_json);
    cJSON *students = cJSON_GetObjectItem(root, "students");    
    
    cJSON *total = cJSON_GetObjectItem(students, "total");      // 获取总数
    
    cJSON *stu_arr = cJSON_GetObjectItem(students, "student");  // 获取 student 数组
    int stu_arr_size = cJSON_GetArraySize(stu_arr);             // 获取 student 数组中元素的个数
    
    cJSON *grade = cJSON_GetObjectItem(root, "grade");
    
    cJSON *subject_arr = cJSON_GetObjectItem(root, "subject");  // 获取 subject 数组
    int subject_arr_size = cJSON_GetArraySize(subject_arr);     // 获取 subject 数组中元素的个数
    
    cJSON *item, *id, *name, *age, *hobby, *sub_value;
    int i;

    printf("total: %d\n", total->valueint);

    printf("\nstu_arr_size: %d\n", stu_arr_size);     // 打印 student 数组中元素的个数
    for(i=0; i<stu_arr_size; ++i)
    {
        item = cJSON_GetArrayItem(stu_arr, i);      // 获取 student 数组中的具体项
        id = cJSON_GetObjectItem(item, "id");
        name = cJSON_GetObjectItem(item, "name");
        age = cJSON_GetObjectItem(item, "age");
        hobby = cJSON_GetObjectItem(item, "hobby");
        printf("id:%-1d, name:%-8s, age:%-2d, hobby:%-10s\n", id->valueint, name->valuestring, age->valueint, hobby->valuestring);
    }

    printf("\ngrade: %s\n", grade->valuestring);

    printf("\nsubject_arr_size: %d\n", subject_arr_size);     // 打印 subject 数组中元素的个数
    printf("subject is: ");
    for(i=0; i<subject_arr_size; ++i)
    {
        sub_value = cJSON_GetArrayItem(subject_arr, i);
        printf("%s ", sub_value->valuestring);
    }
    printf("\n");

    /* 释放空间 */
    if(root != NULL)
    {
        cJSON_Delete(root);
        root = NULL;
        students = NULL;
        total = NULL;
        stu_arr = NULL;
        grade = NULL;
    }

    return 0;
}

  执行结果如下:

linux@linux-VirtualBox:~/myfiles/cJson$ gcc app.c cJSON.c -o app
linux@linux-VirtualBox:~/myfiles/cJson$ ./app
total: 3

stu_arr_size: 3
id:1, name:xiaoming, age:18, hobby:basketball
id:2, name:xiaolan , age:17, hobby:tennis    
id:3, name:xiaohong, age:18, hobby:piano     

grade: senior three

subject_arr_size: 3
subject is: Chinese math English 
 类似资料: