JSON详解

本文部分借鉴 阿阿阿阿阿阿鑫 的博客,特此说明。
https://blog.csdn.net/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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Linux老A

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

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

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

打赏作者

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

抵扣说明:

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

余额充值