热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【libcjson库使用与例程】

     JSON是一种轻量级的数据交换格式。它采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易

      JSON 是一种轻量级的数据交换格式。它采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

      在C语言中一般使用libcjson库进行json数据的解析与创建,下面会使用两个例程分别介绍如何解析和创建json数据。

备注:手动创建json数据可通过一些在线的json数据校验工具。可准确检查出json的语法错误,还可以快速的对json数据进行压缩和转义,便于C程序的调试。见:http://www.bejson.com/

1、json数据解析

使用到的接口有:

cJSON_Parse():解析json字符串;

cJSON_GetObjectItem():获取一个json项目;

cJSON_GetArrayItem():获取一个json数组;

cJSON_Print():转换json数据为字符串;

cJSON_Delete():销毁json数据,注意通过cJSON_Parse()创建的json数据中分配了堆存储,必须通过cJSON_Delete()注销才能释放空间;

待解析的数据如下:


{
"school": "gaoqi",
"type": "aa",
"student_num": 120,
"student_max": 200,
"grade_info": {
"grade_num": 3,
"grade_list": [{
"grade_level": 7,
"people": 40,
"class_info": {
"class_num": 2,
"class_list": [{
"class_id": 1,
"people": 18,
"score_avr": 72.5
},
{
"class_id": 2,
"people": 22,
"score_avr": 72.5
}
]
}
},
{
"grade_level": 8,
"people": 60,
"class_info": {
"class_num": 3,
"class_list": [{
"class_id": 1,
"people": 32,
"score_avr": 83.3
},
{
"class_id": 2,
"people": 18,
"score_avr": 72.5
},
{
"class_id": 3,
"people": 10,
"score_avr": 71.2
}
]
}
},
{
"grade_level": 9,
"people": 21,
"class_info": {
"class_num": 1,
"class_list": [{
"class_id": 1,
"people": 21,
"score_avr": 82.9
}]
}
}
]
}
}

解析例程cjson_test.c


#include
#include
#include
#include "cJSON.h"
const char pBuf[] = "{\"school\":\"gaoqi\",\"type\":\"aa\",\"student_num\":120,\"student_max\":200,\"grade_info\":{\"grade_num\":3,\"grade_list\":[{\"grade_level\":7,\"people\":40,\"class_info\":{\"class_num\":2,\"class_list\":[{\"class_id\":1,\"people\":18,\"score_avr\":72.5},{\"class_id\":2,\"people\":22,\"score_avr\":72.5}]}},{\"grade_level\":8,\"people\":60,\"class_info\":{\"class_num\":3,\"class_list\":[{\"class_id\":1,\"people\":32,\"score_avr\":83.3},{\"class_id\":2,\"people\":18,\"score_avr\":72.5},{\"class_id\":3,\"people\":10,\"score_avr\":71.2}]}},{\"grade_level\":9,\"people\":21,\"class_info\":{\"class_num\":1,\"class_list\":[{\"class_id\":1,\"people\":21,\"score_avr\":82.9}]}}]}}";
int cjsonToValue (cJSON* pMap, char *pcKey, void *pValue)
{
int iRet = -1;
cJSON* pNode = NULL;
if (!pMap || !pcKey || !pValue) {
return (PX_ERROR);
}
/*
* 根据 key 值获取一个项目
*/
if ((pNode = cJSON_GetObjectItem(pMap, pcKey))) {
switch (pNode->type) {
case cJSON_Number: /* 数值类型使用 double 存储 */
*(double *)pValue = pNode->valuedouble;
break;
case cJSON_String: /* 字符串类型 */
strcpy(pValue, pNode->valuestring);
break;
case cJSON_Object: /* 一个 cjson 子项目 */
strcpy(pValue, cJSON_Print(pNode));
break;
default:
break;
}
iRet = 0;
}
return (iRet);
}
int main (int argc, char **argv)
{
int i, j;
cJSON *pRoot = NULL;
cJSON *pGradeInfo = NULL;
cJSON *pGradeList = NULL;
char cString[100] = {0};
double dNum;
double dGradeNum;
pRoot = cJSON_Parse(pBuf); /* 解析 cJSON 字符串 */
if (pRoot == NULL) {
printf("cjson parse error:%s\n", cJSON_GetErrorPtr());
goto __end;
}
/*
* 获取学校信息
*/
if (cjsonToValue(pRoot, "school", cString) || !strlen(cString)) {
printf("cjson get school error\n");
goto __end;
}
printf("school:%s\n", cString);
if (cjsonToValue(pRoot, "type", cString) || !strlen(cString)) {
printf("cjson get type error\n");
goto __end;
}
printf("type:%s\n", cString);
if (cjsonToValue(pRoot, "student_num", &dNum)) {
printf("cjson get student_num error\n");
goto __end;
}
printf("student_num:%d\n", (int)dNum);
if (cjsonToValue(pRoot, "student_max", &dNum)) {
printf("cjson get student_max error\n");
goto __end;
}
printf("student_max:%d\n", (int)dNum);
/*
* 获取年级信息
*/
pGradeInfo = cJSON_GetObjectItem(pRoot, "grade_info");
if (pRoot == NULL) {
printf("cjson parse grade_info error:%s\n", cJSON_GetErrorPtr());
goto __end;
}
if (cjsonToValue(pGradeInfo, "grade_num", &dGradeNum)) {
printf("cjson get grade_num error\n");
goto __end;
}
printf("grade_num:%d\n", (int)dGradeNum);
pGradeList = cJSON_GetObjectItem(pGradeInfo, "grade_list");
if (pGradeList == NULL) {
printf("cjson get grade_list error\n");
goto __end;
}
/*
* 循环读取年级数组信息
*/
for (i = 0; i <(int)dGradeNum; i++) {
cJSON *pGradeItem = NULL;
cJSON *pClassInfo = NULL;
cJSON *pClassList = NULL;
double dClassNum;
pGradeItem = cJSON_GetArrayItem(pGradeList, i);
if (pGradeItem == NULL) {
printf("cjson get grade item error\n");
goto __end;
}
if (cjsonToValue(pGradeItem, "grade_level", &dNum)) {
printf("cjson get grade_level error:%s\n", cJSON_GetErrorPtr());
goto __end;
}
printf("\tgrade_level:%d\n", (int)dNum);
if (cjsonToValue(pGradeItem, "people", &dNum)) {
printf("cjson get people error\n");
goto __end;
}
printf("\tpeople:%d\n", (int)dNum);
/*
* 获取班级信息
*/
pClassInfo = cJSON_GetObjectItem(pGradeItem, "class_info");
if (pClassInfo == NULL) {
printf("cjson parse class_info error:%s\n", cJSON_GetErrorPtr());
goto __end;
}
if (cjsonToValue(pClassInfo, "class_num", &dClassNum)) {
printf("cjson get class_num error\n");
goto __end;
}
printf("\tclass_num:%d\n", (int)dClassNum);
pClassList = cJSON_GetObjectItem(pClassInfo, "class_list");
if (pClassList == NULL) {
printf("cjson get class_list error\n");
goto __end;
}
for (j = 0; j <(INT)dClassNum; j++) {
cJSON *pClassItem = NULL;
pClassItem = cJSON_GetArrayItem(pClassList, j);
if (pClassItem == NULL) {
printf("cjson get class item error\n");
goto __end;
}
if (cjsonToValue(pClassItem, "class_id", &dNum)) {
printf("cjson get class_id error\n");
goto __end;
}
printf("\t\tclass_id:%d\n", (int)dNum);
if (cjsonToValue(pClassItem, "people", &dNum)) {
printf("cjson get people error\n");
goto __end;
}
printf("\t\tpeople:%d\n", (int)dNum);
if (cjsonToValue(pClassItem, "score_avr", &dNum)) {
printf("cjson get score_avr error\n");
goto __end;
}
printf("\t\tscore_avr:%0.2lf\n\n", dNum);
}
printf("\n");
}
__end:
if (pRoot) {
cJSON_Delete (pRoot); /* 销毁 */
}
return (0);
}

执行结果如下:


# /apps/cjson_test/cjson_test
school:gaoqi
type:aa
student_num:120
student_max:200
grade_num:3
grade_level:7
people:40
class_num:2
class_id:1
people:18
score_avr:72.50
class_id:2
people:22
score_avr:72.50
grade_level:8
people:60
class_num:3
class_id:1
people:32
score_avr:83.30
class_id:2
people:18
score_avr:72.50
class_id:3
people:10
score_avr:71.20
grade_level:9
people:21
class_num:1
class_id:1
people:21
score_avr:82.90

 

2、创建一个json结构

使用到的接口有:

cJSON_CreateObject():创建一个json数据结点;

cJSON_AddStringToObject():添加一个字符串数据;

cJSON_AddNumberToObject():添加一个数值数据;

cJSON_AddItemToObject():添加一个json项目;

cJSON_CreateArray():添加一个json数组;

cJSON_Print():转换json数据为字符串;

cJSON_Delete():销毁json数据,注意通过cJSON_Parse()创建的json数据中分配了堆存储,必须通过cJSON_Delete()注销才能释放空间;

创建json结构例程cjson_create.c如下:


#include
#include
#include
#include "cJSON.h"
int main (int argc, char **argv)
{
cJSON *pRoot = NULL;
cJSON *pGradeInfo = NULL;
cJSON *pGradeList = NULL;
int i, j;
char *pOut;
pRoot = cJSON_CreateObject();
/*
* 添加学校信息
*/
cJSON_AddStringToObject(pRoot, "school", "shihua");
cJSON_AddStringToObject(pRoot, "type", "bb");
cJSON_AddNumberToObject(pRoot, "student_num", 120);
cJSON_AddNumberToObject(pRoot, "student_max", 200);
/*
* 添加年级信息
*/
pGradeInfo = cJSON_CreateObject();
cJSON_AddItemToObject(pRoot, "grade_info", pGradeInfo);
cJSON_AddNumberToObject(pGradeInfo, "grade_num", 3);
pGradeList = cJSON_CreateArray();
cJSON_AddItemToObject(pGradeInfo, "grade_list", pGradeList);
for (i = 0; i <3; i++) {
cJSON *pClassInfo = NULL;
cJSON *pClassList = NULL;
cJSON *pItem = cJSON_CreateObject();
cJSON_AddItemToArray(pGradeList, pItem);
cJSON_AddNumberToObject(pItem, "grade_level", 7 + i);
cJSON_AddNumberToObject(pItem, "people", 40);
/*
* 添加班级信息
*/
pClassInfo = cJSON_CreateObject();
cJSON_AddItemToObject(pItem, "class_info", pClassInfo);
cJSON_AddNumberToObject(pClassInfo, "class_num", 2);
pClassList = cJSON_CreateArray();
cJSON_AddItemToObject(pClassInfo, "grade_list", pClassList);
for (j = 0; j <2; j++) {
cJSON *pItem = cJSON_CreateObject();
cJSON_AddItemToArray(pClassList, pItem);
cJSON_AddNumberToObject(pItem, "class_id", j + 1);
cJSON_AddNumberToObject(pItem, "people", 20);
cJSON_AddNumberToObject(pItem, "score_avr", 72.23);
}
}
pOut = cJSON_Print(pRoot);
printf("%s\n", pOut);
cJSON_Delete(pRoot);
return (0);
}

执行结果如下:


# /apps/cjson_create/cjson_create
{
"school": "shihua",
"type": "bb",
"student_num": 120,
"student_max": 200,
"grade_info": {
"grade_num": 3,
"grade_list": [{
"grade_level": 7,
"people": 40,
"class_info": {
"class_num": 2,
"grade_list": [{
"class_id": 1,
"people": 20,
"score_avr": 72.23
}, {
"class_id": 2,
"people": 20,
"score_avr": 72.23
}]
}
}, {
"grade_level": 8,
"people": 40,
"class_info": {
"class_num": 2,
"grade_list": [{
"class_id": 1,
"people": 20,
"score_avr": 72.23
}, {
"class_id": 2,
"people": 20,
"score_avr": 72.23
}]
}
}, {
"grade_level": 9,
"people": 40,
"class_info": {
"class_num": 2,
"grade_list": [{
"class_id": 1,
"people": 20,
"score_avr": 72.23
}, {
"class_id": 2,
"people": 20,
"score_avr": 72.23
}]
}
}]
}
}

 

 

 

 



推荐阅读
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了一种解析GRE报文长度的方法,通过分析GRE报文头中的标志位来计算报文长度。具体实现步骤包括获取GRE报文头指针、提取标志位、计算报文长度等。该方法可以帮助用户准确地获取GRE报文的长度信息。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
author-avatar
Chilldon螴暁鼕
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有