【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
                                                }]
                                }
                        }]
        }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章