我是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;
}
}
}
答案 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分配给-1
或NULL
的值。
请注意,此行为与您的行为完全相同,如果返回为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有同样的“问题”。
您可以更改样式以提前返回值以减少缩进,从而使代码难以阅读,但您需要检查回调。