2

我是 JSON 新手。在我看来,我应该检查从所有对 cJSON_GetObjectItem() 的调用返回的 NULL 指针。但是如果对象中有很多项,那么这种检查就会变得非常冗长。我是否需要检查此调用返回的 NULL,如果需要,有没有比下面显示的更好的方法?

jsonPortArray = cJSON_GetObjectItem(jsonInput,"port");
if (jsonPortArray != NULL)
{
    for (portIndex = 0; portIndex < cJSON_GetArraySize(jsonPortArray); portIndex++)
    {
        jsonPort = cJSON_GetArrayItem(jsonPortArray, portIndex);
        if (jsonPort == 0)
            break;  // Bail out of loop if null ptr.

        // ******* Is this safe? I see this style a lot.
        port[portIndex].portNum = cJSON_GetObjectItem(jsonPort, "portNum")->valueint;
        port[portIndex].portDir = cJSON_GetObjectItem(jsonPort, "portDir")->valueint;
        port[portIndex].portType = cJSON_GetObjectItem(jsonPort, "portType")->valueint;

        /*
        I shortened the list of values to get, but there are MANY.
        */

        // ******* Or do I need to check NULLs for every item, like this?
        if ( cJSON_GetObjectItem(jsonPort, "portNum") != NULL)
        {
            port[portIndex].portNum = cJSON_GetObjectItem(jsonPort, "portNum")->valueint;
        }
    }
}
4

2 回答 2

2

您应该检查 NULL,或者期望您的程序在错误输入时出现段错误。

但是,您可以使其不那么冗长:

#define JSON_OBJECT_NOT_NULL(jsonThing, name) \
    (cJSON_GetObjectItem(jsonThing, name) != NULL ? \
    cJSON_GetObjectItem(jsonThing, name)->valueint : -1)

...
port[portIndex].portNum = JSON_OBJECT_NOT_NULL(jsonPort, "portNum");

在这里,我使用宏和内联 if分配给 的值->valueint-1如果返回是NULL.

请注意,此行为与您的行为不完全相同,如果返回为 NULL,我将值设置为 -1,您在示例中没有采取任何行动。如果您设置为 -1,您仍然需要稍后检测它是无效的 -1 值。

此外,为了便于阅读,我将定义分成多行,\字符转义换行符,这意味着\字符后没有空格,或者将其连接到一行。

#define JSON_OBJECT_NOT_NULL(jsonThing, name) (cJSON_GetObjectItem(jsonThing, name) != NULL ? cJSON_GetObjectItem(jsonThing, name)->valueint : -1)
于 2013-06-25T00:55:24.977 回答
1

好吧,首先确保在检查时使用 NULL 而不是 0。在 C 中是必需的。

但基本上除此之外,没有。你不能做任何其他事情。如果您不知道某个值是否存在,则需要在使用前进行检查。JSON 是非结构化的,在使用强类型语言时需要这样做。Java 也有同样的“问题”。

您可以更改样式以尽早返回值以减少使代码难以阅读的缩进,但您需要检查调用的返回。

于 2013-06-25T00:34:30.080 回答