cJson的使用方法

cJson的使用方法

学长讲了cJson的基础后,做一下整理,并从网上找了一些资料做深入理解。

一 JSON概念

cJSON,目前来说,就只有两个文件,一个cJSON.c,一个cJSON.h文件。使用的时候,自己创建好一个main.c文件后,将头文件include进去

  • 编译时记得在末尾链接libm库
二 JSON结构体
typedef struct cJSON
{
    struct cJSON *next,*prev;
    struct cJSON *child;
    int type;
    char *valuestring;
    int valueint;
    double valuedouble;
    char *string;
}cJSON;
  • 说明:
    • cJSON结构体是一个双向列表,并可以通过child指针访问下一层。
    • type变量决定数据项类型(键的类型),数据项可以是字符串可以是整形,也可以是浮点型。
    • 如果是整形值的话可从valueint
    • 如果是浮点型的话可从valuedouble取出
    • 如果是字符串的话可从valuestring取出
    • string可以理解为节点的名称,综合此处的第二点可以理解为“键”的名称
    • cJSON作为Json格式的解析库,其主要功能无非就是构建和解析Json格式了,用途就是一端将要发送的数据已cjson形式封装,然后发送,另一端收到此数据后,还是按cjson形式解析,就得到想要的数据了。
三 封装成json形式

创建json数据串。这数据串,可能是对象,也可能是数组,也可能是它们的各种组合,其中再加上一些键值对。有一点要先说明:它们的组合,符合父子继承格式--这也是json数据串的特点。

  • 创建一个对象,并向这个对象里添加字符串和整型键值:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"cJSON.h"
int main(void)
{
    cJSON *usr;
    cJSON *arry;
    usr=cJSON_CreateObject();//创建数据跟对象
    cJSON_AddStringToObject(usr,"name","lala");//加入键值,加字符串
    cJSON_AddStringToObject(usr,"passwd","123");//加入键值,加字符串
    cJSON_AddNumberToObject(usr,"num",1);//加整数
    char *out=cJSON_Print(usr);//生成适合阅读的JSON字符串
    printf("%s\n",out);//打印
    //释放内存,很重要!!
    cJSON_Delete(usr);//释放JSON对象
    free(out);//释放生成的字符串
}

![2018-08-14 09-28-19 的屏幕截图](/home/lala/图片/2018-08-14 09-28-19 的屏幕截图.png)

  • 说明:

    • cJSON_CreateObject函数可创建一个根数据项,之后便可向该根数据项中添加string或int等内容,返回的是一个 cJSON的指针,注意,在这个指针用完了以后,需要手工调用 cJSON_Delete(root); 进行内存回收。
    • cJSON_AddNumberToObject向节点中添加子节点,例如此处添加name节点,节点值为字符串”fengxin”
    • 需要注意的是 json 格式的数据,虽然也是一个字符串的样子,但这个时候还是无法当成普通的字符串进行使用,需要调用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);来将json对象转换成普通的字符串,并且都是以该json对象的根为基点。两个API的区别即是:一个是没有格式的:也就是转换出的字符串中间不会有”\n” “\t”之类的东西存在,而cJSON_Print(root);打印出来是人看起来很舒服的格式。
    • 因为函数内部封装有malloc函数,所以使用free函数释放被out占用的内存空间
  • 创建一个数组,并向数组添加一个字符串和一个数字:
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;
}

![2018-08-14 09-43-14 的屏幕截图](/home/lala/图片/2018-08-14 09-43-14 的屏幕截图.png)

  • 对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字:

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

![2018-08-14 09-51-01 的屏幕截图](/home/lala/图片/2018-08-14 09-51-01 的屏幕截图.png)

  • 只要搞清楚父子关系即可
四 解析json得到的数据

解析数据包的过程和组装数据包的过程相反

解析JSON(JSON字符串转结构体)

处理流程:

1.现将普通的json串处理成json对象,也就是所谓的创建json root的过程

cJSON *root;
root=cJSON_Parse(js_string);//将JSON字符串转化为cJSON对象

2.开始拿关键字,但如果关键字还有父层或者祖层,那就需要先从父层开拿,所谓剥洋葱是也!

先说没有父层的:

out={\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1};
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"cJSON.h"
int main(void)
{
    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);
}

![2018-08-14 10-11-02 的屏幕截图](/home/lala/图片/2018-08-14 10-11-02 的屏幕截图.png)

上面的type 已经在cJSON.h里面定义好了,有自己的意义。如果是在严格的场所,应该先判定该 item的type,然后再考虑去拿值。

处理这串数据:

out={\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}
char *s="{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}"
cJSON *root=cJSON_Parse(s);
if(!root)
{
    printf("get root failed !\n");
    return -1;
}
cJSON *js_list=cJSON_GetObjectItem(root,"list");
if(!js_list)
{
    printf("no list!\n");
    return -1;
}
printf("list type is %d\n",js_list->type);
cJSON  *name=cJSON_GetObjectItem(js_list,"name");
if(!name)
{
    printf("No name !\n");
    return -1;
}
printf("name type is %d\n",name->type);
printf("name is %s\n",name->valuestring);
cJSON *age=cJSON_GetObjectItem(js_list,"age");
if(!age)
{
    printf("no age!\n");
    return -1;
}
printf("age type is %d\n",age->type);
printf("age is %d\n",age->valueint);
cJSON *js_other=cJSON_GetObjectItem(root,"other");
if(!js_other)
{
    printf("no list!\n");
    return -1;
}
printf("list type is %d\n",js_other->type);
cJSON *js_name=cJSON_GetObjectItem(js_other,"name");
if(!js_name)
{
    printf("No name!\n");
    return -1;
}
printf("name type is %d\n",js_name->type);
printf("name is %s\n",js_name->valuestring);
if(root)
{
    cJSON_Delete(root);
    return 0;
}

![2018-08-14 10-25-30 的屏幕截图](/home/lala/图片/2018-08-14 10-25-30 的屏幕截图.png)

综合例子:
#include <stdio.h>
#include <math.h>
#include "./cJSON.h"
#include <stdlib.h>
#include <string.h>
struct student 
{
    int id;
    char no[9] ;
    char s_name[20];
};
int main(){

    //创建JSON
    struct student f = {1,"04163002","fujie"};

    cJSON *student = cJSON_CreateObject();//创建数据根对象

    cJSON_AddNumberToObject(student,"id",f.id);// 添加节点(属性)
    /*
    cJSON * id = cJSON_CreateNumber(f.id);
    cJSON_AddItemToObject(student,"id",item);
    */

    cJSON_AddStringToObject(student,"no",f.no);
    cJSON_AddStringToObject(student,"s_name",f.s_name);
    char *out = cJSON_Print(student); // 生成适合阅读的JSON字符串
    printf("适合阅读:\n %s\n",out);
    free(out); // 释放生成的字符串
    out = cJSON_PrintUnformatted(student);// 生成适合传输的JSON字符串
    printf("\n适合传输:\n %s\n",out);
//  free(out);
    cJSON_Delete(student);// 释放内存


    //解析JSON
    struct student ff;
    cJSON *student2 = cJSON_Parse(out);
    ff.id = cJSON_GetObjectItem(student2,"id")->valueint;
    strcpy(ff.no,cJSON_GetObjectItem(student2,"no")->valuestring);
    strcpy(ff.s_name,cJSON_GetObjectItem(student2,"s_name")->valuestring);
    cJSON_Delete(student2);
    free(out);
    printf("\n解析结果: \n id: %d\n no: %s\n s_name: %s\n",ff.id,ff.no,ff.s_name);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值