全面详解c语言使用cJSON解析JSON字符

为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件!

如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更好!

且文件体积大小不到30k,源代码思路也非常清晰,也非常适合研究。

点我下载cJSON

当我们下载好cJSON只需要把.c和.h文件包含文件拷贝到我们工程目录下,并将头文件和实现文件包含进来就可以使用了!

cJSON使用数据结构链表的方式来存储js对象。

 

 

typedef struct cJSON {  //cJSON结构体
       struct cJSON*next,*prev;           /* 遍历数组或对象链的前向或后向链表指针*/
       struct cJSON *child;                   /*数组或对象的孩子节点*/
       int type;                                     /* key的类型*/
       char *valuestring;                       /*字符串值*/
       int valueint;                                /* 整数值*/
       double valuedouble;                    /* 浮点数值*/
       char *string;                               /* key的名字*/
} cJSON;
 

 

正所谓万丈高楼平地起,先从最简单的开始!

 

 

先来介绍四个常用的cJSON函数:

 

cJSON *cJSON_Parse(const char *value);
 

作用:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体

返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL

 

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
作用:获取JSON字符串字段值

返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL

 

 

char  *cJSON_Print(cJSON *item);
作用:将cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串

 

返回值:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL

 

 

void   cJSON_Delete(cJSON *c);
作用:释放位于堆中cJSON结构体内存

 

返回值:无

 

假如说有这样的一个JSON字符串

 

{
 "test_1":"0"
 "test_2":"1"
 "test_3":"2"
} //json_string
 //json_string
这是最简单的JSON字符串

我们首先要先将这个字符串打包成cJSON数据格式

 

cJSON* cjson = cJSON_Parse(json_string);
打包后使用if语句或三目表达式判断一下是否将JSON字符串打包成cJSON数据格式

if(cjson == NULL){
printf("json pack into cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}
 

然后依次获取json字符串中的每个字段的值并打印输出
//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
char* test_1_string = cJSON_GetObjectltem(cjson,"test_1")->valuestring;
char* test_2_string = cJSON_GetObjectltem(cjson,"test_2")->valuestring;
char* test_3_string = cJSON_GetObjectltem(cjson,"test_3")->valuestring;
//打印输出
printf("%s",*test_1_string);
printf("%s",*test_2_string);
printf("%s",*test_3_string);
最后别忘记释放内存

 

 

//delete cjson
cJSON_Delete(cjson);
cJSON_Delete(test_arr);
cJSON_Delete(arr_item);
 

完整代码:

 

#include <stdio.h>
#include <cJSON.h>
int main(){
char* json_string =\ 
//用char* 模拟一个JSON字符串
"{"\
 "test_1":"0"\
 "test_2":"1"\
 "test_3":"2"\
"}";
//JSON字符串到cJSON格式
cJSON* cjson = cJSON_Parse(json_string); 
//判断cJSON_Parse函数返回值确定是否打包成功
if(cjson == NULL){
printf("json pack into cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}
 
//获取字段值
//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
char* test_1_string = cJSON_GetObjectltem(cjson,"test_1")->valuestring;
char* test_2_string = cJSON_GetObjectltem(cjson,"test_2")->valuestring;
char* test_3_string = cJSON_GetObjectltem(cjson,"test_3")->valuestring;
 
//打印输出
printf("%s",*test_1_string);
printf("%s",*test_2_string);
printf("%s",*test_3_string);
 
//delete cjson
cJSON_Delete(cjson);
 
}
是不是很easy?下面来教大家如何使用cJSON解析数组!

{
 "test_1":"1",
 "test_2":"2",
 "test_arr":[{
{
  "test_1":"arr_1",
  "test_2":"arr_2",
  "test_3":"arr_3"
},
{
 "test_1":"1",
 "test_2":"2",
 "test_3":"3"
}
}],
"test_3" :"3"
}//json_arr string
在开始前介绍一个函数

int      cJSON_GetArraySize(cJSON *array);
作用:获取数组成员对象个数
返回值:数组成员对象个数

 


首先第一步打包

 

cJSON* cjson = cJSON_Parse(json_arr_string);
第二步判断打包是否成功

 

 

if(cjson == NULL){
printf("json pack into cjson error...")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}
第三步获取数组对象

cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr");
第四步获取数组对象个数便于循环

int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2
第五步获取test_arr数组对象孩子节点

cJSON* arr_item = test_arr->child;//子对象
第六步循环获取数组下每个字段的值并使用cJSON_Print打印:

for(int i = 0;i <=(arr_size-1)/*0*/;++i){
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3"));
arr_item = arr_item->next;//下一个子对象
}
最后别忘记释放

 

 

cJSON_Delete(cjson);
cJSON_Delete(test_arr);
cJSON_Delete(arr_item);
完整代码:

 

 

#include <stdio.h>
#include <cJSON.h>
int main(){
char* json_string =\ 
//用char* 模拟一个JSON字符串
“{”,\
 "test_1":"1",\
 "test_2":"2",\
 "test_arr":"[{",\
"{",\
  "test_1":"arr_1",\
  "test_2":"arr_2",\
  "test_3":"arr_3",\
"}",\
"{"\
 "test_1":"1",\
 "test_2":"2",\
 "test_3":"3",\
"}",\
"}]",\
"test_3" :"3",\
"}"//json_arr string;
 
//第一步打包JSON字符串
cJSON* cjson = cJSON_Parse(json_arr_string);
 
//判断是否打包成功
if(cjson == NULL){
printf("json pack into cjson error…")
}
else{//打包成功调用cJSON_Print打印输出
cJSON_Print(cjson);
}
 
//获取数组对象
cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr");
 
//获取数组对象个数便于循环
int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2
 
//获取test_arr数组对象孩子节点
cJSON* arr_item = test_arr->child;//子对象
 
//循环获取数组下每个字段的值并使用cJSON_Print打印
for(int i = 0;i <=(arr_size-1)/*0*/;++i){
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2"));
cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3"));
arr_item = arr_item->next;//下一个子对象
}
 
//delete cjson
cJSON_Delete(cjson);
cJSON_Delete(test_arr);
cJSON_Delete(arr_item);
 

 

基本接口说明
创建的JSON格式说明:{}表示一个Object,[]表示一个Array

cJSON_CreateObject:创建一个JSON结构体 
cJSON_AddItemToObject:把一个item添加到JSON结构体里 
cJSON_Print:将JSON格式的字符串转成普通字符串 
cJSON_Parse:将普通字符串转成JSON格式的字符串 
cJSON_Delete:释放JSON结构体
下面这些宏定义可以更快捷地帮助你创建JSON节点

 #define cJSON_AddNullToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateNull())
 #define cJSON_AddTrueToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
 #define cJSON_AddFalseToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
 #define cJSON_AddBoolToObject(object,name,b)   cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
 #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
 #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))

比如如果要添加一个“name”:“Tom”的节点,下面两行代码都是相等的

cJSON_AddStringToObject(root, "name", "Tom")
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Tom"))

 

创建JSON的方法

demo1

    {
        "name": "Tom",
        "age":  25,
        "marry":        true,
        "child":        null
    }

创建demo1的代码实现

char * cjson_create_test1(void)
{
   char * out;
   cJSON *root;

   root = cJSON_CreateObject();
   if(!root)
   {
       printf("cJSON create error!!\n");
       return NULL;
   }

   cJSON_AddItemToObject(root, "name", cJSON_CreateString("Tom"));
   cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(25));
   cJSON_AddItemToObject(root, "marry", cJSON_CreateBool(1));
   cJSON_AddItemToObject(root, "child", cJSON_CreateNull());

   out=cJSON_Print(root);
   cJSON_Delete(root);    

   if(out)
   {
       printf("%s\n", out);
       return out;
   }

   return NULL;
}

 demo2

{
    "name": "Tom",
    "age":  25,
    "marry":        true,
    "children":     [{
                    "name": "May",
                    "age":  2
            }, {
                    "name": "Kendy",
                    "age":  3
            }, {
                    "name": "Mark",
                    "age":  1
            }]
}

创建demo2的实现方法

char * cjson_create_test2(void)
{
    char * out;
    cJSON *root;
    cJSON *child, *child1, *child2, *child3;

    root = cJSON_CreateObject();
    if(!root)
    {
        printf("cJSON create error!!\n");
        return NULL;
    }

    cJSON_AddItemToObject(root, "name", cJSON_CreateString("Tom"));
    cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(25));
    cJSON_AddItemToObject(root, "marry", cJSON_CreateBool(1));

    child = cJSON_CreateArray();    
    CJSON_CHK_FAIL(child, NULL);
    cJSON_AddItemToObject(root, "children", child);

    child1 = cJSON_CreateObject();    
    CJSON_CHK_FAIL(child1, NULL);
    cJSON_AddItemToObject(child1, "name", cJSON_CreateString("May"));
    cJSON_AddItemToObject(child1, "age", cJSON_CreateNumber(2));

    child2 = cJSON_CreateObject();    
    CJSON_CHK_FAIL(child2, NULL);
    cJSON_AddItemToObject(child2, "name", cJSON_CreateString("Kendy"));
    cJSON_AddItemToObject(child2, "age", cJSON_CreateNumber(3));

    child3 = cJSON_CreateObject();    
    CJSON_CHK_FAIL(child3, NULL);
    cJSON_AddItemToObject(child3, "name", cJSON_CreateString("Mark"));
    cJSON_AddItemToObject(child3, "age", cJSON_CreateNumber(1));

    cJSON_AddItemToArray(child, child1);
    cJSON_AddItemToArray(child, child2);
    cJSON_AddItemToArray(child, child3);

    out=cJSON_Print(root);
    cJSON_Delete(root);    

    if(out)
    {
        printf("%s\n", out);      
        return out;
    }

    return NULL;
}

解析JSON的方法

解析上面的demo1

void cjson_parse_test1(void)
{
    cJSON * root;
    cJSON *name, *age, *marry, *child;

    root = cJSON_Parse(cjson_create_test1());   
    if(!root)
    {
        printf("cJSON_Parse error!!\n");
        return;
    }

    name = cJSON_GetObjectItem(root, "name");
    if(name)
    {
        printf("Get name value : %s\n", name->valuestring);
    }

    age = cJSON_GetObjectItem(root, "age");
    if(age)
    {
        printf("Get age value : %d\n", age->valueint);
    }

    marry = cJSON_GetObjectItem(root, "marry");
    if(marry)
    {
        printf("Get marry value : %d\n", marry->valueint);
    }

    child = cJSON_GetObjectItem(root, "child");
    if(child)
    {
        printf("Get child value : %s\n", marry->valuestring);
    }

    cJSON_Delete(root);    
}

解析上面的demo2

void cjson_parse_test2(void)
{
    cJSON * root;
    cJSON *name, *age, *marry, *children;
    cJSON *childNode, *childName, *childAge;

    root = cJSON_Parse(cjson_create_test2());   
    if(!root)
    {
        printf("cJSON_Parse error!!\n");
        return;
    }

    name = cJSON_GetObjectItem(root, "name");
    if(name)
    {
        printf("Get name value : %s\n", name->valuestring);
    }

    age = cJSON_GetObjectItem(root, "age");
    if(age)
    {
        printf("Get age value : %d\n", age->valueint);
    }

    marry = cJSON_GetObjectItem(root, "marry");
    if(marry)
    {
        printf("Get marry value : %d\n", marry->valueint);
    }

    children = cJSON_GetObjectItem(root, "children");
    if(children)
    {
        int size = cJSON_GetArraySize(children);
        printf("Get children size : %d\n", size);

        int i = 0;
        for(i=0; i<size; i++)
        {
            childNode = cJSON_GetArrayItem(children, i);
            if(childNode)
            {                
                childName = cJSON_GetObjectItem(childNode,"name");
                if(childName)
                {            
                    printf("Get child name : %s\n", childName->valuestring);
                }

                childAge = cJSON_GetObjectItem(childNode,"age");
                if(childAge)
                {            
                    printf("Get child age : %d\n", childAge->valueint);
                }
            }

        }
    }

    cJSON_Delete(root);    
}

 

 

 

 

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值