CJSON在C语言中的应用实例讲解

cJSON概念简介:

JSON(JavaScriptObject Notation)是一种轻量级的数据交换格式。可以把JSON的结构理解成无序的、可嵌套的key-value键值对集合,这些key-value键值对是以结构体或数组的形式来组织的。同一级的key-value键值对之间是用一个“,”(逗号)隔开,每个key-value键值对是由一个key后面紧接一个“:”(冒号),冒号后面是这个key对应的value。Key是一个word,由大小写字母、下划线及数字组成,可以由双引号封闭,也可以不加双引号;而value的取值集为:Number、Boolean(true或false)、null、String、Object及Array。

易于人阅读和编写,同时也易于机器解析和生成,已经成为理想的数据交换语言。在C语言中,cJSON一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器,很好的衔接了底层和前端数据的交互处理。

cJSON结构体:

typedefstruct cJSON {

structcJSON *next,*prev;

struct cJSON *child;

int type;

char * valuestring;

int valueint;

double valuedouble;

char *string;

}cJSON;

//cJSON存储的时候是采用链表存储的,其访问方式很像一颗树。每一个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。

不过,只有节点是对象或数组才可以有孩子节点。

cJSON中的type有7种取值:

#define cJSON_False 0

#define cJSON_True 1

#define cJSON_NULL 2

#define cJSON_Number 3

#define cJSON_String 4

#define cJSON_Array 5

#define cJSON_Object 6

Object:对象,也可理解成一个结构体,是以一对大括号封闭起来的无序的key-value键值对集合,例如:{name:"Susan", age:27, birthday:{year:1984, month:2, day:11}};也可以写成:{"name":"Susan", "age":27, "birthday":{"year":1984, "month":2, "day":11}};

Array:数组,JSON的数组是一个以中括号封闭起来的value的集合,即数组内的各个成员的数据类型可以不一样,这一点就跟C/JAVA的数组概念不同了。每个value之间是由一个“,”(逗号)隔开,例如:[123, abc, false, {name:mj}];


代码示例:

      1 #include <stdio.h>
      2 #include "cJSON.h"
      3     
      4 //使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
      5     
      6 //调用cjson函数创建json串
      7 char* createJsonStr()
      8 {   
      9     cJSON * pJsonRoot = NULL;
     10     pJsonRoot = cJSON_CreateObject();//新建一个JSON项目
     11     if ( NULL == pJsonRoot )
     12     {
     13         return NULL;
     14     }   
     15     cJSON_AddStringToObject(pJsonRoot, "sayhi", "hello world!!");//在JSON项中添加了字符串
     16     cJSON_AddBoolToObject(pJsonRoot, "I`m a man", 1);
     17     cJSON * pJsonChild = cJSON_CreateObject();//新建一个JSON项目
     18     if ( NULL == pJsonChild )
     19     {
     20         cJSON_Delete(pJsonRoot);
     21         return NULL;
     22     }
     23     cJSON_AddStringToObject(pJsonChild, "name", "my name is fengdj");
     24     cJSON_AddNumberToObject(pJsonChild, "my age", 30);
     25     cJSON * pJsonSubChild = cJSON_CreateObject();//新建一个JSON项目
     26     if ( NULL == pJsonSubChild)
     27     {
     28         cJSON_Delete(pJsonRoot);
     29         cJSON_Delete(pJsonChild);
     30         return NULL;
     31     }
     32     cJSON_AddStringToObject(pJsonSubChild, "job", "I`m a programmer");
     33     cJSON_AddFalseToObject(pJsonSubChild, "baby");
     34     cJSON_AddItemToObject(pJsonChild, "sub child item", pJsonSubChild);//把pJsonSubChild项目添加到pJsonChild上。
     35     cJSON_AddItemToObject(pJsonRoot, "child item", pJsonChild);//把pJsonChild项目添加到Root项 pJsonRoot
     36     char* lpJsonStr = NULL;
     37     lpJsonStr = cJSON_Print(pJsonRoot); //CJSON的内存的存储的数据转换为字符串格式
     38     cJSON_Delete(pJsonRoot);//因为 child json 和 subchild json 已经被添加到pJsonRoot, 所以只需要delete pJsonRoot,       
        如果你再去delete child 和subchild, 将会因重复释放导致程序coredump
     39         
     40     return lpJsonStr;
     41 }   

        42 
     43 //使用cjson 函数解析json串
     44 void parseJsonStr(char* lpJStr)
     45 {
     46     if( NULL == lpJStr )
     47     {
     48         return;
     49     }   
     50     cJSON* pJson = cJSON_Parse(lpJStr);//将json串解析后存入cjson内存, 并返回cjson实例
     51     if( NULL == pJson )
     52     {
     53         return;
     54     }
     55     if ( pJson->type == cJSON_Object )
     56     {
     57         cJSON* pJson1 = cJSON_GetObjectItem(pJson, "sayhi");//从cjson内获取对应key的值
     58         if ( NULL == pJson1 )
     59         {
     60             return;
     61         }
     62         //pJson1->type
     63         printf("%s\n", pJson1->valuestring);
     64 
     65         //+++++
     66         cJSON* pNext = pJson1->next; //cJSON_GetObjectItem(pJson, "I`m a man");
     67         if ( NULL != pNext )
     68         {
     69             int iValue = pNext->valueint;
     70             printf("+++%d\n", iValue);
     71             cJSON* pPre = pNext->prev;
     72             if ( NULL != pPre )
     73             {
     74                 printf("++%s\n", pPre->valuestring);
     75             }
     76         }
     77         //++++++
     78 
     79         cJSON* pJson2 = cJSON_GetObjectItem(pJson, "I`m a man");
     80         if ( NULL == pJson2 )
     81         {
     82             return;
     83         }
     84         //pJson2->type
     85         printf("%d\n", pJson2->valueint);

     86 
     87         cJSON* pJson3 = cJSON_GetObjectItem(pJson, "child item");
     88         if ( NULL == pJson3 )
     89         {
     90             return;
     91         }
     92         if ( pJson3->type == cJSON_Object )
     93         {
     94             cJSON* pJson31 = cJSON_GetObjectItem(pJson3, "name");
     95             if ( NULL == pJson31 )
     96             {
     97                 return;
     98             }
     99             printf("%s\n", pJson31->valuestring);
    100             cJSON* pJson32 = cJSON_GetObjectItem(pJson3, "my age");
    101             if ( NULL == pJson32 )
    102             {
    103                 return;
    104             }
    105             printf("%f\n", pJson32->valuedouble);
    106             printf("%d\n", pJson32->valueint);
    107         }
    108         cJSON* pJson4 = cJSON_GetObjectItem(pJson3, "sub child item");
    109         if ( NULL == pJson4 )
    110         {
    111             return;
    112         }
    113         if ( pJson4->type == cJSON_Object )
    114         {
    115             cJSON* pJson41 = cJSON_GetObjectItem(pJson4, "job");
    116             if ( NULL == pJson41 )
    117             {
    118                 return;
    119             }
    120             printf("%s\n", pJson41->valuestring);
    121         }
    122     }
    123     cJSON_Delete(pJson);    //程序结束前,回收cjson实例,上述子节点的cjson实例会一并回收
    124 }

    125 
    126 //释放json串内存
    127 void releaseJsonStr(char *lpJsonStr)
    128 {
    129     if ( NULL != lpJsonStr )
    130     {
    131         free(lpJsonStr);
    132     }
    133 }

    135 //创建json数组
    136 char* createJsonArray(int iSize)
    137 {
    138     cJSON * JsonArray = cJSON_CreateArray();
    139     if ( NULL == JsonArray )
    140     {
    141         return NULL;
    142     }
    143     int i = 0;
    144     for ( i=0; i<iSize-2; i++)
    145     {
    146         cJSON_AddNumberToObject(JsonArray, "hehe", i);
    147     }
    148     for ( i=iSize; i<iSize+2; i++)
    149     {
    150         cJSON_AddStringToObject(JsonArray, "he", "test");
    151     }
    152     char * lpArrayJsonStr = cJSON_Print(JsonArray);
    153     cJSON_Delete(JsonArray);
    154     return lpArrayJsonStr;
    155 }
    156 

    157 //解析cjson数组
    158 void parseArray(char* lpJsonArrayStr)
    159 {
    160     if ( NULL == lpJsonArrayStr)
    161     {
    162         return;
    163     }
    164     cJSON * pJsonRoot = NULL;
    165     pJsonRoot = cJSON_Parse(lpJsonArrayStr);
    166     if ( NULL == pJsonRoot )
    167     {
    168         return;
    169     }
    170     if ( pJsonRoot->type == cJSON_Array )
    171     {
    172         int iSize = cJSON_GetArraySize(pJsonRoot);
    173         int iIndex = 0;
    174         for( ; iIndex<iSize; iIndex++)
    175         {
    176             cJSON* pItem = cJSON_GetArrayItem(pJsonRoot, iIndex);
    177             if ( NULL == pItem )
    178             {
    179                 continue;
    180             }
    181             if ( pItem->type == cJSON_String )
    182             {
    183                 printf("%s\n", pItem->valuestring);
    184             }
    185             else if ( pItem->type == cJSON_Number )
    186             {
    187                 int iValue = pItem->valueint;//若你期望的是int,则访问valueint,若期望的是double,则访问valuedouble
    188                 printf("%d\n", iValue);
    189             }
    190         }
    191     }
    192     cJSON_Delete(pJsonRoot);
    193     return ;
    194 }

    195 
    196 int main()
    197 {
    198     //创建json 串和解析json串
    199     char * lpStr = createJsonStr();
    200     if( NULL == lpStr )
    201     {
    202         return -1;
    203     }
    204     printf("%s\n", lpStr);
    205     parseJsonStr(lpStr);
    206     releaseJsonStr(lpStr);
    207 
    208     //创建json数组和解析json数组
    209     char * lpArrayJsonStr = createJsonArray(6);
    210     if ( NULL == lpArrayJsonStr )
    211     {
    212         return -1;
    213     }
    214     printf("%s\n", lpArrayJsonStr);
    215     parseArray(lpArrayJsonStr);
    216     releaseJsonStr(lpArrayJsonStr);
    217     return 0;
    218 }
    219 
    220 //CJSON在内存中的存储方式是用链表进行存储的,所以在进行操作的时候,我们可见的部分全部是用指针进行操作的。
    221 
    222

=============================out  put=================================== 

[fengdj@localhost testCJson]$ gcc *.c -lm    
[fengdj@localhost testCJson]$ ./a.out 
{
        "sayhi":        "hello world!!",
        "I`m a man":    true,
        "child item":   {
                "name": "my name is fengdj",
                "my age":       30,
                "sub child item":       {
                        "job":  "I`m a programmer",
                        "baby": false
                }
        }
}
hello world!!
+++1
++hello world!!
1
my name is fengdj
30.000000
30
I`m a programmer
[0, 1, 2, 3, "test", "test"]
0
1
2
3
test
test

=============================================================================

用法:

1、只需在函数中includecJSON.h头文件,然后和cJSON.c或库文件libcJSON.a一起编译即可使用。

2、具体函数用法详见cJSON.h中注释


猜你喜欢

转载自blog.csdn.net/fengdijiang/article/details/56277759