【libcjson 库使用与例程】

      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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
                                                }]
                                }
                        }]
        }
}

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stone8761

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值