This shows you the differences between two versions of the page.
— |
prog:c_cpp:250728-001:index [2025/07/28 10:51] (current) jethro created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ~~NOTOC~~ | ||
+ | ====== 一個輕量級C語言JSON解析器 (2025-07-28) ====== | ||
+ | * Source - [[https://blog.csdn.net/Mculover666/article/details/103796256]] | ||
+ | * {{:prog:c_cpp:250728-001:pasted:20250728-103840.png?300}} | ||
+ | ====== Local Backup ====== | ||
+ | * 本文深入探討了JSON數據格式及其C語言實現cJSON的使用。介紹了JSON的基本概念、語法規則,cJSON的特性、數據結構及設計思想。詳細講解了如何使用cJSON封裝和解析JSON數據,包括創建、添加、輸出JSON數據以及解析方法和注意事項。 | ||
+ | ===== 一. JSON與cJSON ===== | ||
+ | * JSON是一種文本數據交換格式,獨立與語言存在。 | ||
+ | * 基本格式為key:value形式,還有數組。 | ||
+ | * 例如:<sxh json>{ | ||
+ | "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" | ||
+ | } | ||
+ | }] | ||
+ | }</sxh> | ||
+ | * cJSON是一個c語言編寫的JSON解釋器,僅有一個cJSON.h和cJSON.c文件。 | ||
+ | * 附鏈接: [[https://sourceforge.net/projects/cjson/|cJSON]] | ||
+ | ===== 二、cJSON用法 ===== | ||
+ | * 1. 構造/解析cJSON | ||
+ | * 示例:<sxh jason>{ | ||
+ | "action":"mode_set", | ||
+ | "mode":1 | ||
+ | }</sxh> | ||
+ | * 構造數據: | ||
+ | * <sxh c>cJSON *JsData = cJSON_CreateObject(); | ||
+ | cJSON_AddStringToObject(JsData, "action", "mode_set"); | ||
+ | cJSON_AddNumberToObject(JsData, "mode", 1);</sxh> | ||
+ | * 解析數據: | ||
+ | * <sxh c>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);</sxh> | ||
+ | * 擴展: | ||
+ | * 組數據時,還有以下api | ||
+ | * <sxh c>cJSON_AddBoolToObject(object, key, value); | ||
+ | cJSON_AddFalseToObject(object, key); | ||
+ | cJSON_AddTrueToObject(object, key); | ||
+ | cJSON_AddNullToObject(object, null);</sxh> | ||
+ | * 2.嵌套JSON | ||
+ | * <sxh c>{ | ||
+ | "action":"mode_set", | ||
+ | "mode":1 | ||
+ | "datalist": | ||
+ | { | ||
+ | "username":"admin", | ||
+ | "password":"admin" | ||
+ | } | ||
+ | }</sxh> | ||
+ | * 組數據: | ||
+ | * <sxh c>cJSON *JsDataList = cJSON_CreateObject(); | ||
+ | cJSON_AddItemToObject(JsData, JsDataList); | ||
+ | cJSON_AddStringToObject(JsDataList, "username", "admin"); | ||
+ | cJSON_AddStringToObject(JsDataList, "password", "admin");</sxh> | ||
+ | * 解析數據: | ||
+ | * <sxh c>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);</sxh> | ||
+ | * 3.數組 | ||
+ | * 示例:<sxh c>{ | ||
+ | "action":"mode_set", | ||
+ | "mode":1, | ||
+ | "datalist": | ||
+ | { | ||
+ | "username":"admin", | ||
+ | "password":"admin" | ||
+ | } | ||
+ | "register": | ||
+ | ["{ | ||
+ | "status":"0", | ||
+ | "msg":"Success." | ||
+ | }"] | ||
+ | }</sxh> | ||
+ | * 組數據: | ||
+ | * <sxh c>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");</sxh> | ||
+ | * 解析數據: | ||
+ | * <sxh c>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); | ||
+ | }</sxh> | ||
+ | * 4. 替换和删除cJSON | ||
+ | * 示例: | ||
+ | * <sxh c>{ | ||
+ | "action":"mode_set", | ||
+ | "mode":1 | ||
+ | "datalist": | ||
+ | { | ||
+ | "username":"admin", | ||
+ | "password":"admin" | ||
+ | } | ||
+ | }</sxh> | ||
+ | * 替換password: | ||
+ | * <sxh c>cJSON *JsDataList = NULL; | ||
+ | cJSON_ReplaceItemInObject(JsDataList, "password", "admin123");</sxh> | ||
+ | * 删除password: | ||
+ | * <sxh c>cJSON_DeleteItemFromObject(JsDataList, "password");</sxh> | ||
+ | * 5.格式化輸出cJSON數據 | ||
+ | * <sxh c>UINT1 *pu1Data = NULL; | ||
+ | UINT1 au1Data[1024] = {0}; | ||
+ | pu1Data = cJSON_PrintUnformatted(JsData); | ||
+ | SPRINTF(au1Data, pu1Data);</sxh> | ||
+ | * 6.內存申請與釋放 | ||
+ | * 以下函數調用時都會申請內存,如果不釋放內存會造成內存泄露: | ||
+ | * <sxh c>cJSON_Parse(); | ||
+ | cJSON_CreateObject(); | ||
+ | cJSON_CreateArray(); | ||
+ | cJSON_Print(); | ||
+ | cJSON_PrintUnformatted();</sxh> | ||
+ | * 釋放內存: | ||
+ | * <sxh c>cJSON_Delete(); | ||
+ | cJSON_free();</sxh> | ||
+ | * 用法解釋: | ||
+ | * 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後,使用前都要判空。 | ||
+ | * <sxh c>cJSON *JsData = NULL; | ||
+ | JsData = cJSON_CreateObject(); | ||
+ | if (JsData == NULL) | ||
+ | return FAILURE;</sxh> | ||
+ | ====== Reference ===== | ||
+ | * | ||
+ | ====== ====== | ||
+ | * {{counter}} person(s) visited this page until now. | ||
+ | * [[:prog:c_cpp:index|Back]] | ||
+ | ====== ====== | ||
+ | <html> | ||
+ | <!-- | ||
+ | PDF for A4-Portrait: {{pdfjs 50%,450px > xxx.pdf?page-fit}} | ||
+ | PDF for A4-Landscape: {{pdfjs 700px,500px > xxx.pdf?page-fit}} | ||
+ | PDF for iPad Note: {{pdfjs 700px,500px > xxx.pdf?page-fit}} | ||
+ | {{gallery>work-note:2024-08:12?lightbox&0&150x150&crop}} | ||
+ | |||
+ | Youtube: {{youtube>large:XXXXX}} | ||
+ | Code Highlight: <sxh php; first-line: 70; highlight: [89,92]; title: New title attribute in action> | ||
+ | |||
+ | --> | ||
+ | </html> |