1.2 解析JSON字符串

1.2 解析JSON字符串

  在cJSON中解析JSON字符串是第一步最重要的步骤,而cJSON提供了4个解析JSON字符串的函数,包括对完整的JSON串的解析,解析固定长度的JSON串的解析,以及解析可能含义非JSON语法的错误信息的JSON串的解析函数,而这些函数还能在适当的时候解析出错的时候返回整个JSON中有效的JSON,以及解析出错的位置。下面我们通过一个示例来介绍一下,我这里使用了Visual Studio进行了代码的编写。

 1 #include <iostream>
 2 #include "cJSON.h"
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     ///////////////////////////////////// cJSON初始化JSON串的几种方式 /////////////////////////////////////
 8     //  1.直接通过内存中的JSON来进行初始化
 9     /// 1.1 先手动构建一个JSON字符串串
10     const char jsonStr1[] = "{\"Name\":\"XiaoXin\",\"Age\":23,\"Information\":{\"Year\":2023,\"Month\":12}}";
11     /// 1.2 然后使用cJSON_Parse函数来根据刚刚的JSON字符串来创建cJSON对象
12     cJSON*json1 = cJSON_Parse(jsonStr1);
13     cout << cJSON_Print(json1) << endl;//可以使用cJSON_Print来输出JSON,但是这个输出的话,会带有很多空格(方便调试看到),如果不需要的话可以使用unFormat
14     cout << cJSON_PrintUnformatted(json1) << endl;
15     /// 1.3 我们一旦使用完cJSON对象之后就需要释放掉,防止内存泄露
16     cJSON_Delete(json1);
17     json1 = NULL;
18 
19 
20     //  2.按照固定的长度来解析JSON串(这种场景,假设我们收到的JSON串是不完整的(这可能会用在网络通信中收到的JSON),但是我们如果知道前n个长度确确实实是有效的JSON上下文,那么我们就可以用这个函数)
21     /// 2.1 构造一个不完整的JSON串
22     const char jsonStr2[] = "{\"Key1\":12,\"Key2\":13},Name:";//前21个字符都是有效的串
23     /// 2.2 通过前21个有效的字符来构造一个cJSON对象
24     cJSON*json2 = cJSON_ParseWithLength(jsonStr2, 21);
25     cout << cJSON_PrintUnformatted(json2) << endl;
26     /// 2.3 记得释放
27     cJSON_Delete(json2);
28     json2 = NULL;
29 
30     //  3.通过自定义行为来解析JSON串(我们可以通过cJSON_ParseWithOpts来传入适当的参数来规定如何解析JSON串[尤其是一些不完整的JSON串],以及还可以当解析到无效位置时,可以做什么)
31     /*
32         cJSON_ParseWithOpts(
33             const char* value,//要解析的JSON串
34             const char** return_parse_end,//这个二级指针会自动定位到解析失败的那个字符串的首字符地址上,我们可以通过这个地址计算出是字符串哪个下标出出错了(若传入NULL,则视为不使用这个参数)
35             cJSON_bool require_null_terminated//作用‌:控制是否强制要求输入字符串在JSON数据结束后立即跟随null终止符(\0)。
36                 设置为 1 (true)‌:解析器会检查 JSON 结束后是否紧跟 \0。如果后面还有非空白字符(如垃圾数据),则视为解析错误。这有助于防止解析被截断的数据或包含尾部垃圾的数据。
37                 设置为 0 (false)‌:解析器在解析完合法的 JSON 结构后即停止,忽略后面的内容(只要前面的 JSON 语法正确)。
38         );
39     */
40     /// 3.1 定义一个带有错误的不完整的JSON串
41     const char jsonStr3[] = "{\"Key1\":12,\"Key2\":13},Name:";
42     const char* return_parse_end = NULL;
43     //如果说我们定义了需要在解析出错时得到在哪个位置出错了的地址,以及我们强制要求解析失败了就返回空的JSON对象并停止一切动作
44     cJSON*json3 = cJSON_ParseWithOpts(jsonStr3, &return_parse_end, 1);
45     if (!json3)
46     {
47         cout << "使用cJSON_ParseWithOpts解析不完整的JSON串失败,且返回了空的JSON对象,因为用户定义了当解析失败时强行返回空JSON对象" << endl;
48         cout << "JSON解析失败!失败的字符串是" << return_parse_end << ",解析出错的位置是:" << (return_parse_end - jsonStr3) << endl;
49     }
50     cJSON_Delete(json3);
51     json3 = NULL;
52     //如果说我们定义了需要在解析出错时得到哪个字符串位置出错了,以及即使是出错,我们也需要解析出出错位置前面有效的JSON对象,那么就可以将第三个参数改为0
53     cJSON* json4 = cJSON_ParseWithOpts(jsonStr3, &return_parse_end, 0);
54     if (!json4)
55     {
56         cout << "JSON解析失败!虽然指定了出错时仍然返回有效的JSON对象,但JSON根本无有效的JSON子串" << endl;
57     }
58     else
59     {
60         cout << "JSON虽然解析失败,但目标JSON字符串中仍然有有效的JSON对象,但解析出错的字符串是:" << return_parse_end << ",解析出错的位置在:" << (return_parse_end-jsonStr3) << endl;
61         cout << cJSON_PrintUnformatted(json4) << endl;
62     }
63     cJSON_Delete(json4);
64     json4 = NULL;
65 
66     //  4.对于cJSON_ParseWithLengthOpts函数,相比于cJSON_ParseWithOpts就是多了一个长度控制,基本上是用在网络传输中读取固定长度的JSON时,若解析失败则需要做出相关操作的场景。这个函数读者可以自己去试验。
67     return 0;
68 }
函数名称   支持指定JSON长度? 支持返回解析错误或错误的位置? 强制要求JSON输入必须以\0结尾? 使用场景
cJSON_Parse 不支持 不支持 适用于在内存中构建或解析100%完整且不会出错的JSON字符串
cJSON_ParseWithLength 支持 不支持 否,因为我们可以解析JSON串中的某一段长度的子JSON片段 适用于解析固定长度的JSON字符串。尤其是时候解析网络数据中指定长度的JSON子片段。
cJSON_ParseWithOpts 不支持 支持,若参数3为1,则当解析失败时视为返回的cJSON对象无效,且可以通过配置参数来获得解析出错的位置(通过指针相减计算得出)。若参数3为0,则看被解析的JSON串中除了无效的JSON内容之外若还有有效的子JSON串,那么就返回有效的cJSON串上下文,且可以通过配置第二参数得到解析出错的位置。 适用于解析在内存中构建的可能含有无效JSON内容但又含有有效JSON的字符串上下文。
cJSON_ParseWithLengthOpts 支持 支持,若参数3为1,则当解析失败时视为返回的cJSON对象无效,且可以通过配置参数来获得解析出错的位置(通过指针相减计算得出)。若参数3为0,则看被解析的JSON串中除了无效的JSON内容之外若还有有效的子JSON串,那么就返回有效的cJSON串上下文,且可以通过配置第二参数得到解析出错的位置。 否,我们可以通过传入的Length参数解析指定的长度的JSON上下文,且这个函数还能在指定长度的上下文中进一步视JSON的情况知道有效的JSON位置和解析出错的位置 功能最完整的组合版,同时支持长度控制、解析结束位置返回、终止符校验,是嵌入式/网络场景下最安全的解析选择

  本节小结:

  本节我们学习了cJSON的4个解析JSON字符串的函数,分别是cJSON_Parse;cJSON_ParseWithLength;cJSON_ParseWithOpts以及cJSON_ParseWithLengthOpts。以及我们初步还认识了如何使用cJSON_PrintUnformat和cJSON_Print来讲将cJSON对象输出到标准输出上。以及最重要的当我们使用完cJSON对象后,需要使用cJSON_Delete来释放cJSON对象以防止内存泄露。希望读者能从本节有所收获。有所总结。

posted @ 2026-07-05 17:02  蜡笔小新Pointer  阅读(4)  评论(0)    收藏  举报