0

我正在编写一小段 c 代码来使用 gcc 中的 cJSON 库解析 json 数组元素。解析成功,但数组元素的打印显示为空。不确定是什么问题。

需要传入 src、dst 和设备索引列表的 json 数组输入。

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) <<
4

1 回答 1

1

你的主要问题是你打电话cJSON_GetArrayItem而不是cJSON_GetObjectItem. 属性是对象的一部分,而不是直接包含数组的一部分。切换呼叫,您显示的代码将大部分工作。

其他,次要的东西:

  • 你失踪#include <string.h>strlen
  • %d在打印结果时使用strlen. 由于strlen返回 a size_t,因此您应该%zu改用。
  • 您正在打印jsrcPid,jdstPidjdevIdxs作为字符串 ( %s),但它们实际上是struct cJSON *,因此您应该使用%p并强制转换为(void*)

如果您启用警告,编译器可能会告诉您所有这些信息。使用 GCC 时,请始终使用 flags -Wall -Wextra -Wpedantic。此外,通过给出 、 或 中的一个来告诉编译器您使用的是哪个-std=c90C标准。-std=c99-std=c11-std=c18

于 2019-09-01T09:22:52.317 回答