从json调用检查空指针的C代码

时间:2013-06-25 00:31:45

标签: c json

我是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;
        }
    }
}

2 个答案:

答案 0 :(得分: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");

如果返回值为->valueint,我会使用宏和inline if分配给-1NULL的值。

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

另外,为了可读性,我将定义分成多行,\个字符正在转换换行符,这意味着\个字符后面没有空格,或者将它连接到一行。

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

答案 1 :(得分:1)

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

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

您可以更改样式以提前返回值以减少缩进,从而使代码难以阅读,但您需要检查回调。