在读取 JSON 数组元素时使用 cJSON 问题
Using cJSON issue in reading JSON array elements
我正在编写一小段 c 代码来使用 gcc 中的 cJSON 库解析 json 数组元素。
解析成功,但数组元素的打印结果为空。
不确定是什么问题。
需要通过json src、dst 和设备索引列表的数组输入。
https://jsonlint.com/ 验证的输出
第一个数据:
{
"NPCDevMoveReqList": [{
"srcPid": "1",
"destPid": "2",
"devIdxs": ["1", "2", "3"]
},
{
"srcPid": "1",
"destPid": "3",
"devIdxs": ["4", "5", "6"]
}
]
}
第二个数据:
{
"NPCDevMoveReqList": [{
"srcPid": 1,
"destPid": 2,
"devIdxs": [1, 2, 3]
}]
}
文件路径&编译方式
/home/ccode/jsonchk.c
/home/ccode/cJSON
gcc -L cJSON/ -lcjson jsonchk.c -o jsonchkary.o
export LD_LIBRARY_PATH=/home/ccode/cJSON
代码:
#include "stdio.h"
#include "cJSON/cJSON.h"
#define REASON_INPUTVALUES_JSONPARSER_ERROR 21
//
///home/ccode/jsonchk.c
//gcc -L cJSON/ -lcjson jsonchk.c -o jsonchk.o
//export LD_LIBRARY_PATH=/home/ccode/cJSON
//
int parsejsonstr(void)
{
char jsoninput[500] = { 0 };
snprintf( (char *)jsoninput, sizeof(jsoninput),
"{\"NPCDevMoveReqList\":[{\"srcPid\":\"1\",\"destPid\":\"2\",\"devIdxs\":[\"1\",\"2\",\"3\"]},{\"srcPid\":\"1\",\"destPid\":\"3\",\"devIdxs\":[\"4\",\"5\",\"6\"]}]}");
printf("jsonstrinput>>:%s\n", jsoninput);
cJSON *jSON_devmove_data = cJSON_Parse(jsoninput);
if(jSON_devmove_data == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d main parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
cJSON * json_devmove_reqlist = cJSON_GetObjectItem(jSON_devmove_data, "NPCDevMoveReqList");
if(jSON_devmove_data == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d reqlist parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
int idx=0;
cJSON* jsrcPid = NULL;
cJSON* jdstPid = NULL;
cJSON* jdevIdxs = NULL;
for (idx = 0 ; idx < cJSON_GetArraySize(json_devmove_reqlist) ; idx++)
{
cJSON * json_subitem = cJSON_GetArrayItem(json_devmove_reqlist, idx);
if(json_subitem == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d idxsub parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
jsrcPid = cJSON_GetArrayItem(json_subitem, "srcPid");
jdstPid = cJSON_GetArrayItem(json_subitem,"destPid");
jdevIdxs = cJSON_GetArrayItem(json_subitem, "devIdxs");
printf("\n>>>moveDevicesJsonArray aryidx:%d src:%s dst:%s devidxs:%s <<\n",
idx, jsrcPid, jdstPid, jdevIdxs);
}
return 1;
}
void main(void)
{
int rval = parsejsonstr();
printf("jsonparsestr call res>>:%d\n", rval);
}
输出:
第一次尝试:
[ccode]$./jsonchkary.o
jsonstrinput>>:{"NPCDevMoveReqList":[{"srcPid":"1","destPid":"2","devIdxs":["1"," 2","3"]},{"srcPid":"1","destPid":"3","devIdxs":["4","5","6"]} ]}
>>>moveDevicesJsonArray aryidx:0 src:(null) dst:(null) devidxs:(null) <<
>>>moveDevicesJsonArray aryidx:1 src:(null) dst:(null) devidxs:(null) <<
jsonparsestr call res>>:1
第二次尝试:
[ccode]$ ./jsonchkary.o
jsonstrinput>>:{"NPCDevMoveReqList":[{"srcPid":1,"destPid":2,"devIdxs":[1,2,3]}]}
>>>moveDevicesJsonArray aryidx:0 src:(null) dst:(null) devidxs:(null) <<
您的主要问题是您调用的是 cJSON_GetArrayItem
而不是 cJSON_GetObjectItem
。属性是对象的一部分,而不是包含数组的直接部分。切换调用,您显示的代码将大部分起作用。
其他次要内容:
- 您缺少
#include <string.h>
strlen
。
- 您在打印
strlen
的结果时使用了 %d
。由于 strlen
returns 和 size_t
,您应该使用 %zu
代替。
- 您将
jsrcPid
、jdstPid
和 jdevIdxs
打印为字符串 (%s
),但它们实际上是 struct cJSON *
,因此您应该使用%p
并转换为 (void*)
.
如果您启用警告,编译器可能会告诉您所有这些。使用 GCC 时,始终使用标志 -Wall -Wextra -Wpedantic
。另外,通过给出 -std=c90
、-std=c99
、-std=c11
或 -std=c18
.
之一告诉编译器您使用的是哪个 C 标准
我正在编写一小段 c 代码来使用 gcc 中的 cJSON 库解析 json 数组元素。 解析成功,但数组元素的打印结果为空。 不确定是什么问题。
需要通过json src、dst 和设备索引列表的数组输入。
https://jsonlint.com/ 验证的输出
第一个数据:
{
"NPCDevMoveReqList": [{
"srcPid": "1",
"destPid": "2",
"devIdxs": ["1", "2", "3"]
},
{
"srcPid": "1",
"destPid": "3",
"devIdxs": ["4", "5", "6"]
}
]
}
第二个数据:
{
"NPCDevMoveReqList": [{
"srcPid": 1,
"destPid": 2,
"devIdxs": [1, 2, 3]
}]
}
文件路径&编译方式
/home/ccode/jsonchk.c
/home/ccode/cJSON
gcc -L cJSON/ -lcjson jsonchk.c -o jsonchkary.o
export LD_LIBRARY_PATH=/home/ccode/cJSON
代码:
#include "stdio.h"
#include "cJSON/cJSON.h"
#define REASON_INPUTVALUES_JSONPARSER_ERROR 21
//
///home/ccode/jsonchk.c
//gcc -L cJSON/ -lcjson jsonchk.c -o jsonchk.o
//export LD_LIBRARY_PATH=/home/ccode/cJSON
//
int parsejsonstr(void)
{
char jsoninput[500] = { 0 };
snprintf( (char *)jsoninput, sizeof(jsoninput),
"{\"NPCDevMoveReqList\":[{\"srcPid\":\"1\",\"destPid\":\"2\",\"devIdxs\":[\"1\",\"2\",\"3\"]},{\"srcPid\":\"1\",\"destPid\":\"3\",\"devIdxs\":[\"4\",\"5\",\"6\"]}]}");
printf("jsonstrinput>>:%s\n", jsoninput);
cJSON *jSON_devmove_data = cJSON_Parse(jsoninput);
if(jSON_devmove_data == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d main parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
cJSON * json_devmove_reqlist = cJSON_GetObjectItem(jSON_devmove_data, "NPCDevMoveReqList");
if(jSON_devmove_data == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d reqlist parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
int idx=0;
cJSON* jsrcPid = NULL;
cJSON* jdstPid = NULL;
cJSON* jdevIdxs = NULL;
for (idx = 0 ; idx < cJSON_GetArraySize(json_devmove_reqlist) ; idx++)
{
cJSON * json_subitem = cJSON_GetArrayItem(json_devmove_reqlist, idx);
if(json_subitem == NULL)
{
printf("\nError moveDevicesJsonArray mvJsonArrayBuf:%.24s mvJsonArrayBuf:%d idxsub parsefail",
jsoninput, strlen(jsoninput));
return REASON_INPUTVALUES_JSONPARSER_ERROR;
}
jsrcPid = cJSON_GetArrayItem(json_subitem, "srcPid");
jdstPid = cJSON_GetArrayItem(json_subitem,"destPid");
jdevIdxs = cJSON_GetArrayItem(json_subitem, "devIdxs");
printf("\n>>>moveDevicesJsonArray aryidx:%d src:%s dst:%s devidxs:%s <<\n",
idx, jsrcPid, jdstPid, jdevIdxs);
}
return 1;
}
void main(void)
{
int rval = parsejsonstr();
printf("jsonparsestr call res>>:%d\n", rval);
}
输出:
第一次尝试: [ccode]$./jsonchkary.o jsonstrinput>>:{"NPCDevMoveReqList":[{"srcPid":"1","destPid":"2","devIdxs":["1"," 2","3"]},{"srcPid":"1","destPid":"3","devIdxs":["4","5","6"]} ]}
>>>moveDevicesJsonArray aryidx:0 src:(null) dst:(null) devidxs:(null) <<
>>>moveDevicesJsonArray aryidx:1 src:(null) dst:(null) devidxs:(null) <<
jsonparsestr call res>>:1
第二次尝试:
[ccode]$ ./jsonchkary.o
jsonstrinput>>:{"NPCDevMoveReqList":[{"srcPid":1,"destPid":2,"devIdxs":[1,2,3]}]}
>>>moveDevicesJsonArray aryidx:0 src:(null) dst:(null) devidxs:(null) <<
您的主要问题是您调用的是 cJSON_GetArrayItem
而不是 cJSON_GetObjectItem
。属性是对象的一部分,而不是包含数组的直接部分。切换调用,您显示的代码将大部分起作用。
其他次要内容:
- 您缺少
#include <string.h>
strlen
。 - 您在打印
strlen
的结果时使用了%d
。由于strlen
returns 和size_t
,您应该使用%zu
代替。 - 您将
jsrcPid
、jdstPid
和jdevIdxs
打印为字符串 (%s
),但它们实际上是struct cJSON *
,因此您应该使用%p
并转换为(void*)
.
如果您启用警告,编译器可能会告诉您所有这些。使用 GCC 时,始终使用标志 -Wall -Wextra -Wpedantic
。另外,通过给出 -std=c90
、-std=c99
、-std=c11
或 -std=c18
.