cJSON 使用详解

本文详细介绍了CJSON库的使用,包括如何解析JSON字符串,获取JSON对象的值,以及如何构造JSON对象。通过示例代码展示了如何递归遍历JSON结构并打印键值对,以及如何添加节点构建JSON。内容涵盖了cJSON_Parse、cJSON_Print等关键函数的用法。
摘要由CSDN通过智能技术生成

cJSON 使用详解

文章内容转自:https://www.cnblogs.com/catgatp/p/6379955.html
封装成构建以及解析函数的代码网页:

https://www.jb51.cc/json/289736.html
https://blog.csdn.net/jenie/article/details/106729511
基础详解:
https://blog.csdn.net/xiaolixi199311/article/details/79083356
复杂应用讲解:https://blog.csdn.net/nihaocaofei/article/details/91492555

由于c语言中,没有直接的字典,字符串数组等数据结构,所以要借助结构体定义,处理json。如果有对应的数据结构就方便一些, 如python中用json.loads(json)就把json字符串转变为内建的数据结构处理起来比较方便。

cjson库文件下载:

sourceforge地址



一个重要概念:

    在cjson中,json对象可以是json,可以是字符串,可以是数字。。。

cjson数据结构定义:

复制代码
#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

typedef struct cJSON {
struct cJSON *next,prev; / next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON child; / An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

int type;                    /* The type of the item, as above. cjson结构的类型上面宏定义的7中之一*/

char *valuestring;            /* The item's string, if type==cJSON_String */
int valueint;                /* The item's number, if type==cJSON_Number */
double valuedouble;            /* The item's number, if type==cJSON_Number */

char *string;                /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */

} cJSON;
复制代码

一、解析json

    用到的函数,在cJSON.h中都能找到:

复制代码
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON cJSON_Parse(const char value);//从 给定的json字符串中得到cjson对象
/
Render a cJSON entity to text for transfer/storage. Free the char
when finished. */
extern char cJSON_Print(cJSON item);//从cjson对象中获取有格式的json对象
/
Render a cJSON entity to text for transfer/storage without any formatting. Free the char
when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);//从cjson对象中获取无格式的json对象

/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);//删除cjson对象,释放链表占用的内存空间

/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON array);//获取cjson对象数组成员的个数
/
Retrieve item number “item” from array “array”. Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON array,int item);//根据下标获取cjosn对象数组中的对象
/
Get item “string” from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);//根据键获取对应的值(cjson对象)

/* For analysing failed parses. This returns a pointer to the parse error. You’ll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);//获取错误字符串
复制代码
要解析的json

复制代码
{
“semantic”: {
“slots”: {
“name”: “张三”
}
},
“rc”: 0,
“operation”: “CALL”,
“service”: “telephone”,
“text”: “打电话给张三”
}
复制代码
代码:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include “cJSON.h”

void printJson(cJSON * root)//以递归的方式打印json的最内层键值对
{
for(int i=0; i<cJSON_GetArraySize(root); i++) //遍历最外层json键值对
{
cJSON * item = cJSON_GetArrayItem(root, i);
if(cJSON_Object == item->type) //如果对应键的值仍为cJSON_Object就递归调用printJson
printJson(item);
else //值不为json对象就直接打印出键和值
{
printf("%s->", item->string);
printf("%s\n", cJSON_Print(item));
}
}
}

int main()
{
char * jsonStr = “{“semantic”:{“slots”:{“name”:“张三”}}, “rc”:0, “operation”:“CALL”, “service”:“telephone”, “text”:“打电话给张三”}”;
cJSON * root = NULL;
cJSON * item = NULL;//cjson对象

root = cJSON_Parse(jsonStr);     
if (!root) 
{
    printf("Error before: [%s]\n",cJSON_GetErrorPtr());
}
else
{
    printf("%s\n", "有格式的方式打印Json:");           
    printf("%s\n\n", cJSON_Print(root));
    printf("%s\n", "无格式方式打印json:");
    printf("%s\n\n", cJSON_PrintUnformatted(root));

    printf("%s\n", "一步一步的获取name 键值对:");
    printf("%s\n", "获取semantic下的cjson对象:");
    item = cJSON_GetObjectItem(root, "semantic");//
    printf("%s\n", cJSON_Print(item));
    printf("%s\n", "获取slots下的cjson对象");
    item = cJSON_GetObjectItem(item, "slots");
    printf("%s\n", cJSON_Print(item));
    printf("%s\n", "获取name下的cjson对象");
    item = cJSON_GetObjectItem(item, "name");
    printf("%s\n", cJSON_Print(item));

    printf("%s:", item->string);   //看一下cjson对象的结构体中这两个成员的意思
    printf("%s\n", item->valuestring);
                    

    printf("\n%s\n", "打印json所有最内层键值对:");
    printJson(root);
}
return 0;    

}
复制代码
二、构造json:

构造 json比较简单,添加json对象即可。参照例子一看大概就明白了。

主要就是用,cJSON_AddItemToObject函数添加json节点。

复制代码
xtern cJSON *cJSON_CreateObject(void);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
复制代码
例子: 要构建的json:

复制代码
“semantic”: {
“slots”: {
“name”: “张三”
}
},
“rc”: 0,
“operation”: “CALL”,
“service”: “telephone”,
“text”: “打电话给张三”
}
复制代码
代码:

复制代码
#include <stdio.h>
#include “cJSON.h”

int main()
{
cJSON * root = cJSON_CreateObject();
cJSON * item = cJSON_CreateObject();
cJSON * next = cJSON_CreateObject();

cJSON_AddItemToObject(root, "rc", cJSON_CreateNumber(0));//根节点下添加
cJSON_AddItemToObject(root, "operation", cJSON_CreateString("CALL"));
cJSON_AddItemToObject(root, "service", cJSON_CreateString("telephone"));
cJSON_AddItemToObject(root, "text", cJSON_CreateString("打电话给张三"));
cJSON_AddItemToObject(root, "semantic", item);//root节点下添加semantic节点
cJSON_AddItemToObject(item, "slots", next);//semantic节点下添加item节点
cJSON_AddItemToObject(next, "name", cJSON_CreateString("张三"));//添加name节点

printf("%s\n", cJSON_Print(root));

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值