JSON详解

本文详细介绍了cJSON库的基本概念、数据结构及其在JSON格式数据的构建与解析中的应用。通过实例演示如何创建和解析JSON数据,适用于需要了解或使用cJSON库的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文部分借鉴 阿阿阿阿阿阿鑫 的博客,特此说明。
https://blog.youkuaiyun.com/fengxinlinux/article/details/53121287

一.JSON格式简述

JSON(JavaScriptObject Notation, JS 对象标记) 是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
cJSON从名字可知,整个项目都是以极标准的C来写的,意思说,可以跨各种平台使用了。cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。

二.cJSON结构体

typedef struct cJSON {  
 struct cJSON *next,*prev;   
 struct cJSON *child;   
 int type;   
 char *valuestring;   
 int valueint;  
 double valuedouble;   
 char *string;   
} cJSON;  

说明1.cJSON是使用链表来存储数据的,其访问方式很像一颗树。每一个节点可以有兄弟节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。只有节点是对象或数组时才可以有孩子节点。

说明2.type是键(key)的类型,一共有7种取值,分别是:False,Ture,NULL,Number,String,Array,Object。若是Number类型,则valueint或valuedouble中存储着值。若期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。若是String类型的,则valuestring中存储着值,可以访问valuestring得到值

说明3.string中存放的是这个节点的名字,可理解为key的名称。

说明4.cJSON作为Json格式的解析库,其主要功能无非就是构建和解析Json格式了,用途就是一端将要发送的数据已cjson形式封装,然后发送,另一端收到此数据后,还是按cjson形式解析,就得到想要的数据了。

三.封装为JSON格式

3.1 创建一个对象,并向这个对象里添加字符串和整型键值
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"cJSON.h"
    int main()
    {
            cJSON * usr;
            cJSON *arry;
            usr=cJSON_CreateObject();   //创建根数据对象
            cJSON_AddStringToObject(usr,"name","fengxin");  //加入键值,加字符串
            cJSON_AddStringToObject(usr,"passwd","123");
            cJSON_AddNumberToObject(usr,"num",1);  //加整数

            char *out = cJSON_Print(usr);   //将json形式打印成正常字符串形式
            printf("%s\n",out);

            // 释放内存  
            cJSON_Delete(usr);  
            free(out);    
    }

    运行结果:
    {
    "name": "fengxin",
    "passwd":   "123",
    "num":  1
    }

    API说明:
    1.cJSON_CreateObject函数可创建一个根数据项,之后便可向该根数据项中添加string或int等内容,返回的是一个 cJSON的指针,注意,在这个指针用完了以后,需要手工调用 cJSON_Delete(root); 进行内存回收。因为内部malloc申请了内存
    2.cJSON_AddNumberToObject向节点中添加子节点,例如此处添加name节点,节点值为字符串"fengxin"
    3.需要注意的是  json 格式的数据,虽然也是一个字符串的样子,但这个时候还是无法当成普通的字符串进行使用,需要调用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);来将json对象转换成普通的字符串,并且都是以该json对象的根为基点。两个API的区别即是:一个是没有格式的:也就是转换出的字符串中间不会有"\n" "\t"之类的东西存在,而cJSON_Print(root);打印出来是人看起来很舒服的格式。
    4.因为函数内部封装有malloc函数,所以使用free函数释放被out占用的内存空间
3.2 创建一个数组,并向数组添加一个字符串和一个数字:
        int create_js(void)
        {
            cJSON *root, *js_body;
            root = cJSON_CreateArray();
            cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
            cJSON_AddItemToArray(root, cJSON_CreateNumber(10)); 
            {
                char *s = cJSON_PrintUnformatted(root);
                if(s){
                   printf(" %s \n",s);
                    free(s);
                }
            }
            if(root)
            cJSON_Delete(root);

            return 0;

        }

        int main(int argc, char **argv)
        {
            create_js();
            return 0;
        }

        运行结果:
        ["Hello world",10]
3.3 对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字:
        int create_js(void)
    {
        cJSON *root, *js_body, *js_list;
        root = cJSON_CreateObject();
        cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray());
        cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject());
        cJSON_AddStringToObject(js_list,"name","fengxin");
        cJSON_AddNumberToObject(js_list,"status",100);

        {
            char *s = cJSON_PrintUnformatted(root);
            if(s){
                printf(" %s \n",s);
                free(s);
            }
        }
        if(root)
            cJSON_Delete(root);

        return 0;
    }

    int main(int argc, char **argv)
    {
        create_js();
        return 0;
    }

    运行结果:
    {"body":[{"name":"fengxin","status":100}]}

四.解析JSON格式包得到数据

4.1 首先将普通的json串处理成json对象
    cJSON *root;
root = cJSON_Parse(js_string);
4.2 取关键字之无父层次,但如果关键字还有父层或者祖层,那就需要先从父层开拿,剥洋葱一样:
out={\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}

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

int main()
{
    cJSON *json,*json_name,*json_passwd,*json_num;
    char* out="{\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}";

    json = cJSON_Parse(out); //解析成json形式
    json_name = cJSON_GetObjectItem( json , "name" );  //获取键值内容
    json_passwd = cJSON_GetObjectItem( json , "passwd" );
    json_num = cJSON_GetObjectItem( json , "num" );

    printf("name:%s,passwd:%s,num:%d\n",json_name->valuestring,json_passwd->valuestring,json_num->valueint);

    cJSON_Delete(json);  //释放内存 
    free(out);
}

运行结果:
name:fengxin,passwd:123,num:1
4.3 取关键字之有父层次
out={\"list\":{\"name\":\"hahaha\"}}

    char *s = "{\"list\":{\"name\":\"hahaha\"}}";
        cJSON *root = cJSON_Parse(s); //解析成json形式
        cJSON *js_list = cJSON_GetObjectItem(root, "list");//获取键值(节点值)
        cJSON *name = cJSON_GetObjectItem(js_list, "name");
        printf("name is %s\n",name->valuestring);

        if(root){
            cJSON_Delete(root);
                return 0;
            }

        结果:
        name is xiao hong
### JSON 格式详解 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时也便于机器解析和生成[^1]。它的设计目标是成为一种比 XML 更加简单、高效的替代方案。 #### 数据结构 JSON 的核心是由键值对组成的对象以及有序列表构成的数组。以下是其主要组成部分: - **对象**:一组无序的键/值对集合,其中键必须为字符串,而值可以是任何合法的 JSON 类型。 - **数组**:一个有序的值序列。 - **基本数据类型**:支持字符串、数值、布尔值、`null` 和嵌套的对象或数组。 #### 语法示例 下面是一个典型的 JSON 对象示例: ```json { "name": "Alice", "age": 25, "isStudent": false, "skills": ["Python", "Java", "C++"], "address": { "city": "Beijing", "zipCode": "100000" } } ``` 在这个例子中,“name”、“age”等都是键名,对应的值分别为字符串、整数和其他复杂类型的组合[^2]。 ### 使用方法 在 Web 开发领域,JSON 被广泛用于前后端之间的数据传输。通过 JavaScript 或其他编程语言中的内置函数,可以轻松实现 JSON 字符串与原生对象间的转换。 #### 解析 JSON 当接收到服务器返回的 JSON 文本时,通常需要将其转化为程序可以直接操作的形式。例如,在 JavaScript 中可以通过 `JSON.parse()` 方法完成这一过程[^3]。 ```javascript const jsonString = '{"result":"success","code":200}'; const parsedData = JSON.parse(jsonString); console.log(parsedData.result); // 输出 'success' ``` #### 序列化 JSON 反之,如果要发送数据到服务端,则可能需要用 `JSON.stringify()` 将对象转回成字符串形式。 ```javascript const obj = { name: "Bob", age: 30 }; const stringifiedObj = JSON.stringify(obj); console.log(stringifiedObj); // 输出 '{"name":"Bob","age":30}' ``` 需要注意的是,在实际项目里处理来自外部源的 JSON 数据之前应该做充分的安全校验以防潜在风险[^4]。 ### 安全注意事项 尽管 JSON 提供了一种非常方便的方式来表示结构化的信息,但它并非完全没有安全隐患。特别是对于那些未经验证就直接使用的远程 API 返回的结果来说更是如此。所以建议始终遵循最佳实践——仅信任已知可靠的输入并实施适当级别的防护措施对抗恶意行为者尝试利用漏洞发起攻击的可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值