User Tools

Site Tools


prog:c_cpp:250728-001:index

一個輕量級C語言JSON解析器 (2025-07-28)

Local Backup

  • 本文深入探討了JSON數據格式及其C語言實現cJSON的使用。介紹了JSON的基本概念、語法規則,cJSON的特性、數據結構及設計思想。詳細講解了如何使用cJSON封裝和解析JSON數據,包括創建、添加、輸出JSON數據以及解析方法和注意事項。

一. JSON與cJSON

  • JSON是一種文本數據交換格式,獨立與語言存在。
  • 基本格式為key:value形式,還有數組。
  • 例如:
    {
    "action":"set",
    "mac":["00:17:62:51:29:21"],
    "password":"admin",
    "dataList":
        [{
        "url_path":"/apply.cgi",
        "method":"POST",
        "Template":"register",
        "data":
            {
            "action":"mode_set",
            "mode":"1",
            "username":"prouser",
            "password":"admin" 
            }
        }]
    }
  • cJSON是一個c語言編寫的JSON解釋器,僅有一個cJSON.h和cJSON.c文件。
  • 附鏈接: cJSON

二、cJSON用法

  • 1. 構造/解析cJSON
    • 示例:
      {
         "action":"mode_set",
         "mode":1
      }
    • 構造數據:
      • cJSON *JsData = cJSON_CreateObject();
        cJSON_AddStringToObject(JsData, "action", "mode_set");
        cJSON_AddNumberToObject(JsData, "mode", 1);
    • 解析數據:
      • char  c1Data[100] = 
        " 
        {
           \"action\":\"cloud_set\",
           \"mode\":1
        }
        " 
        cJSON  *JsData = NULL;
        cJSON  *pValue = NULL;
        JsData = cJSON_Parse(c1Data);
        pValue = cJSON_GetObjectItem(JsData, "action");
        printf("action : %s \r\n", pValue->valuestring);
        pValue = cJSON_GetObjectItem(JsData, "mode");
        printf("mode : %d \r\n", pValue->valuestring);
    • 擴展:
      • 組數據時,還有以下api
      • cJSON_AddBoolToObject(object, key, value);
        cJSON_AddFalseToObject(object, key);
        cJSON_AddTrueToObject(object, key);
        cJSON_AddNullToObject(object, null);
  • 2.嵌套JSON
    • {
         "action":"mode_set",
         "mode":1
         "datalist":
                  {
                      "username":"admin",
                      "password":"admin" 
                  }
      }
    • 組數據:
      • cJSON *JsDataList = cJSON_CreateObject();
        cJSON_AddItemToObject(JsData, JsDataList);
        cJSON_AddStringToObject(JsDataList, "username", "admin");
        cJSON_AddStringToObject(JsDataList, "password", "admin");
    • 解析數據:
      • cJSON *JsDataList = NULL;
        cJSON *pValue = NULL;
        JsDataList = cJSON_GetObjectItem(JsData, "datalist");
        pValue = cJSON_GetObjectItem(datalist, "username");
        printf("username : %s \r\n", pValue->valuestring);
        pValue = cJSON_GetObjectItem(datalist, "password");
        printf("password : %s \r\n", pValue->valuestring);
  • 3.數組
    • 示例:
      {
         "action":"mode_set",
         "mode":1,
         "datalist":
                  {
                      "username":"admin",
                      "password":"admin" 
                  }
         "register":
                   ["{
                      "status":"0",
                      "msg":"Success." 
                   }"]
      }
    • 組數據:
      • cJSON *JsRegisterArr = cJSON_CreateArray();
        cJSON *JsRegisterObj = cJSON_CreateObject();
        cJSON_AddItemToObject(JsData, "register", JsRegisterArr);
        cJSON_AddItemToArray(JsRegisterArr, JsRegisterObj);
        cJSON_AddStringToObject(JsRegisterObj, "status", "0");
        cJSON_AddStringToObject(JsRegisterObj, "msg", "Success");
    • 解析數據:
      • cJSON *JsRegisterArr = NULL;
        cJSON *JsRegisterObj = NULL;
        cJSON *pValue = NULL;
        UINT4  u4DataSize = 0; 
        JsRegisterArr = cJSON_GetObjectItem(JsData, "register");
        u4DataSize = cJSON_GetArraySize(JsRegisterArr);
        for (UINT4 u4Index = 0; u4Index < u4DataSize; u4Index ++)
        {
           JsRegisterObj = cJSON_GetArrayItem(JsRegisterArr, u4Index)
           pValue = cJSON_GetObjectItem(JsRegisterObj, "status");
           printf("status : %s \r\n", pValue->valuestring);
           pValue = cJSON_GetObjectItem(JsRegisterObj, "msg");
           printf("msg : %s \r\n", pValue->valuestring);
        }
  • 4. 替换和删除cJSON
    • 示例:
      • {
           "action":"mode_set",
           "mode":1
           "datalist":
                    {
                        "username":"admin",
                        "password":"admin" 
                    }
        }
    • 替換password:
      • cJSON *JsDataList = NULL;
        cJSON_ReplaceItemInObject(JsDataList, "password", "admin123");
    • 删除password:
      • cJSON_DeleteItemFromObject(JsDataList, "password");
  • 5.格式化輸出cJSON數據
    • UINT1  *pu1Data = NULL;
      UINT1  au1Data[1024] = {0};
      pu1Data = cJSON_PrintUnformatted(JsData);
      SPRINTF(au1Data, pu1Data);
  • 6.內存申請與釋放
    • 以下函數調用時都會申請內存,如果不釋放內存會造成內存泄露:
    • cJSON_Parse();
      cJSON_CreateObject();
      cJSON_CreateArray();
      cJSON_Print();
      cJSON_PrintUnformatted();
    • 釋放內存:
    • cJSON_Delete();
      cJSON_free();
    • 用法解釋:
      • 1. 調用cJSON_Parse,cJSON_CreateObject,cJSON_CreateArray時,使用cJSON_Delete釋放內存,比如JsData = cJSON_CreateObject(), DataListArr = cJSON_CreateArray();cJSON_AddItemToArray(DataListArr, JsData);這種情況只要cJSON_Delete(JsData), 這樣也會同時釋放DataListArr的內存。
      • 2. 如果是調用cJSON_Print,cJSON_PrintUnformatted時,則使用cJSON_free();
  • 建議:
    • 因為涉及申請內存及釋放內存,所以在每次creat一個cJSON後,使用前都要判空。
    • cJSON *JsData = NULL;
      JsData = cJSON_CreateObject();
      if (JsData == NULL)
         return FAILURE;

Reference

  • 3 person(s) visited this page until now.

prog/c_cpp/250728-001/index.txt · Last modified: 2025/07/28 10:51 by jethro