cJSON介绍
a.结构体cJSON
typedef struct cJSON {
struct cJSON *next,*prev; /* next是获取下一个元素数据,prev是获取前一个元素数据 */
struct cJSON *child; /* 获取第一个元素数据,当需要获取下一个时,就得使用next了. */
int type; /* 当前的json类型对象、数组、字符串、数字、null、true、false等 */
char *valuestring; /* 字符串值, if type==cJSON_String */
int valueint; /* 整形类型值, if type==cJSON_Number */
double valuedouble; /* 浮点数类型值, if type==cJSON_Number */
char *string; /* 这个是键 */
} cJSON;
b.type类型,与下面的宏进行判断
/* cJSON Types: */
#define cJSON_False 0 // true
#define cJSON_True 1 // false
#define cJSON_NULL 2 // NULL
#define cJSON_Number 3 // 数字
#define cJSON_String 4 // 字符串
#define cJSON_Array 5 // 数组
#define cJSON_Object 6 // 对象
c.字符串生成cjson指针的函数,使用后需要调用cJSON_Delete进行释放
extern cJSON *cJSON_Parse(const char *value);
// 释放cJSON_Parse返回的指针
extern void cJSON_Delete(cJSON *c);
d.cjson指针指针生成字符串的函数
// 这个生成的字符串有做格式调整
extern char *cJSON_Print(cJSON *item);
// 这个没有作格式调整,就是一行字符串显示
extern char *cJSON_PrintUnformatted(cJSON *item);
// 需要释放它们返回的指针内存,否则会造成内存泄漏。
/* cjson库的使用 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "cJSON.h"
/*
说明:
组装成json效率并不高,并不推荐json,字符串远比json快,但是字符串表示不了对象,protobuf虽然快,但是依赖于第三方库,很棘手
*/
//数据解析
int testPause(const char* pcJson)
{
cJSON* pstRoot = NULL;
cJSON* pstNode = NULL;
cJSON* pstFeat = NULL;
cJSON* pstArray = NULL;
cJSON* pstAudio = NULL;
cJSON* pstRole = NULL;
cJSON* pstTmp = NULL;
int arraySize = 0;
int i = 0, j = 0;
int featSize = 0;
char* p = NULL;
if (NULL == pcJson)
{
return -1;
}
//解析json字符串
pstRoot = cJSON_Parse(pcJson);
if (NULL == pstRoot)
{
return -1;
}
do
{
//获取json对象
pstAudio = cJSON_GetObjectItem(pstRoot, "audio");
/*
注意点:
注意cjson库是如何判断字符串的
if (pstAudio && strlen(pstAudio->valuestring))
这种判断是不正确的,当pstAudio不是一个字符串类型时,pstAudio->valuestring实际上就是NULL,strlen(NULL)会直接导致崩溃
*/
if (NULL == pstAudio || cJSON_String != pstAudio->type)
{
printf("--no audio info .---\n");
break;
}
//获取字符串型json对象的值
printf("====audio info %s=======\n", pstAudio->valuestring);
pstArray = cJSON_GetObjectItem(pstRoot, "array");
if (NULL == pstArray)
{
printf("--no array info .---\n");
break;
}
//提取json数组
//1.获取数组长度
arraySize = cJSON_GetArraySize(pstArray);
if (0 == arraySize)
{
printf("--no array info .---\n");
break;
}
for (i = 0; i < arraySize; i++)
{
pstNode = cJSON_GetArrayItem(pstArray, i);
if (pstNode)
{
//获取角色信息
pstRole = cJSON_GetObjectItem(pstNode, "role");
if (NULL == pstRole || cJSON_Number != pstNode->type)
{
printf("--no role info .---\n");
break;
}
// 修改角色信息
cJSON_ReplaceItemInObject(pstNode, "role", cJSON_CreateNumber(3));
//获取声纹信息
pstFeat = cJSON_GetObjectItem(pstNode, "feat");
if (NULL == pstFeat)
{
printf("--no feat info .---\n");
break;
}
//获取声纹长度
featSize = cJSON_GetArraySize(pstFeat);
if (0 == featSize)
{
printf("--no feat size info .---\n");
break;
}
for (j = 0; j < featSize; j++)
{
pstTmp = cJSON_GetArrayItem(pstFeat, j);
printf("==feat[%lf]==\n", pstTmp->valuedouble);
}
}
}
p = cJSON_Print(pstRoot);
printf("[ testPause ] |%s|\n", p);
} while (0);
// 释放资源
if (pstRoot)
{
cJSON_Delete(pstRoot);
pstRoot = NULL;
}
if (p)
{
free(p);
p = NULL;
}
return 0;
}
//数据组装
char* testAssemble(void)
{
cJSON* pstRoot = NULL;
cJSON* pstNode = NULL;
cJSON* pstFeat = NULL;
cJSON* pstArray = NULL;
float aFeat[10] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 0.0f };
char* pOutput = NULL;
//创建普通json对象
pstRoot = cJSON_CreateObject();
assert(pstRoot);
pstNode = cJSON_CreateObject();
assert(pstNode);
//创建float数组类型json对象
pstFeat = cJSON_CreateFloatArray(aFeat, 10);
assert(pstFeat);
cJSON_AddNumberToObject(pstNode, "role", 1);
cJSON_AddItemToObject(pstNode, "feat", pstFeat);
//创建一个json对象数组
pstArray = cJSON_CreateArray();
assert(pstArray);
//将一个json对象加入到json数组中
cJSON_AddItemToArray(pstArray, pstNode);
//布尔值添加
cJSON_AddStringToObject(pstRoot, "audio", "test.wav");
cJSON_AddItemToObject(pstRoot, "array", pstArray);
//输出json字符串(内存需要自己释放)
pOutput = cJSON_Print(pstRoot);
// 释放资源
if (pstRoot)
{
cJSON_Delete(pstRoot);
pstRoot = NULL;
}
return pOutput;
}
int main()
{
char* pcJson = NULL;
pcJson = testAssemble();
if (NULL == pcJson)
{
printf("----[testAssemble]-----failed-----\n");
return -1;
}
//打印数据
printf("|%s|\n", pcJson);
printf("\n");
//解析json
testPause(pcJson);
//释放资源
if (pcJson)
{
free(pcJson);
pcJson = NULL;
}
printf("-----ok------\n");
getchar();
return 0;
}