在读取JSON数组元素时使用cJSON问题

时间:2019-09-01 07:02:58

标签: c cjson

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

需要传递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) <<

1 个答案:

答案 0 :(得分:1)

您的主要问题是您正在呼叫cJSON_GetArrayItem而不是cJSON_GetObjectItem。这些属性是对象的一部分,而不是包含数组的直接一部分。切换通话,您显示的代码通常可以正常工作。

其他小事:

  • 您缺少#include <string.h>的{​​{1}}。
  • 打印strlen的结果时,您正在使用%d。由于strlen返回了strlen,因此您应该改用size_t
  • 您正在将%zujsrcPidjdstPid打印为字符串(jdevIdxs),但是它们实际上是%s,因此应使用{{ 1}}并强制转换为struct cJSON *

如果启用了警告,则编译器可能已经将所有这些告诉了您。使用GCC时,请始终使用标志%p。另外,通过给(void*)-Wall -Wextra -Wpedantic-std=c90-std=c99中的一个来告诉编译器您使用哪种C标准。