cJSON键值解析

cJSON键值解析,c,json,cjson,C,Json,Cjson,我使用cJSON解析存储在testdata.JSON文件中的JSON,如下所示: { "text": "HelloWorld!!", "parameters": [{ "length": 10 }, { "width": 16 }, { "height": 16 } ] } cJSON *parameters = cJ

我使用cJSON解析存储在
testdata.JSON
文件中的JSON,如下所示:

{
    "text": "HelloWorld!!",
    "parameters": [{
            "length": 10
        },
        {
            "width": 16
        },

        {
            "height": 16
        }
    ]
}
cJSON *parameters = cJSON_GetObjectItem(root, "parameters");
int parameters_count = cJSON_GetArraySize(parameters);
printf("Parameters:\n");
for (int i = 0; i < parameters_count; i++) {

    cJSON *parameter = cJSON_GetArrayItem(parameters, i);
    int length = cJSON_GetObjectItem(parameter, "length")->valueint;
    int width = cJSON_GetObjectItem(parameter, "width")->valueint;
    int height = cJSON_GetObjectItem(parameter, "height")->valueint;
    printf("%d %d %d\n",length, width, height);
}
通过以下操作,我可以访问
文本
字段

int main(int argc, const char * argv[]) {

    //open file and read into buffer

    cJSON *root = cJSON_Parse(buffer);
    char *text = cJSON_GetObjectItem(root, "text")->valuestring;
    printf("text: %s\n", text); 
}
注意:这些参数是动态的,因为根据JSON文件包含的内容,可以有更多的参数,例如
区域
,等等。我的想法是,我有一个包含所有这些参数的
struct
,我必须检查JSON中提供的参数是否存在,并相应地设置值。 结构的
如下所示:

typedef struct {
   char *path;
   int length;
   int width;
   int height;
   int volume;
   int area;
   int angle;
   int size;
} JsonParameters;
我试着这样做:

{
    "text": "HelloWorld!!",
    "parameters": [{
            "length": 10
        },
        {
            "width": 16
        },

        {
            "height": 16
        }
    ]
}
cJSON *parameters = cJSON_GetObjectItem(root, "parameters");
int parameters_count = cJSON_GetArraySize(parameters);
printf("Parameters:\n");
for (int i = 0; i < parameters_count; i++) {

    cJSON *parameter = cJSON_GetArrayItem(parameters, i);
    int length = cJSON_GetObjectItem(parameter, "length")->valueint;
    int width = cJSON_GetObjectItem(parameter, "width")->valueint;
    int height = cJSON_GetObjectItem(parameter, "height")->valueint;
    printf("%d %d %d\n",length, width, height);
}
cJSON*parameters=cJSON_GetObjectItem(根,“参数”);
int parameters\u count=cJSON\u GetArraySize(参数);
printf(“参数:\n”);
对于(int i=0;ivalueint;
int width=cJSON_GetObjectItem(参数,“宽度”)->valueint;
int height=cJSON_GetObjectItem(参数“height”)->valueint;
printf(“%d%d%d\n”,长度、宽度、高度);
}
这将返回
内存访问错误(内存转储)
并且我必须说明哪些是键。如前所述,我不知道参数是什么


如何存储键值对(
“length”:10
“width”:16
“height”:16
等),以及如何根据
JsonParameters
中的有效参数检查键?

下面是一个示例程序,它从示例JSON中遍历
parameters
数组的所有元素,并打印出数组中每个对象的字段名称:

#include <stdio.h>
#include <cJSON.h>

int main(void) {
  const char *json_string = "{\"text\":\"HelloWorld!!\",\"parameters\":[{\"length\":10},{\"width\":16},{\"height\":16}]}";

  cJSON *root = cJSON_Parse(json_string);
  cJSON *parameters = cJSON_GetObjectItemCaseSensitive(root, "parameters");
  puts("Parameters:");
  cJSON *parameter;
  cJSON_ArrayForEach(parameter, parameters) {
    /* Each element is an object with unknown field(s) */
    cJSON *elem;
    cJSON_ArrayForEach(elem, parameter) {
      printf("Found key '%s', set to %d\n", elem->string, elem->valueint);     
    }
  }

  cJSON_Delete(root);
  return 0;
}
#包括
#包括
内部主(空){
const char*json_string=“{\'text\':\'HelloWorld!!\',\'parameters\':[{\'length\':10},{\'width\':16},{\'height\':16}];
cJSON*root=cJSON_Parse(json_字符串);
cJSON*parameters=cJSON_GetObjectItemCaseSensitive(根,“参数”);
看跌期权(“参数:”);
cJSON*参数;
cJSON_ArrayForEach(参数,参数){
/*每个元素都是具有未知字段的对象*/
cJSON*elem;
cJSON_ArrayForEach(元素、参数){
printf(“找到键“%s”,设置为%d\n”,elem->string,elem->valueint);
}
}
cJSON_删除(根目录);
返回0;
}
您可以将每个字段名与您关心的字段名列表进行比较(简单的方法是使用一堆
if
/
else if
strcmp()
),为每个字段设置结构的适当字段


这里最重要的是使用
cJSON\u ArrayForEach
宏遍历数组的两个元素(cJSON将JSON数组表示为链表,并且像代码中那样按索引获取每个元素,使得遍历数组成为
O(N^2)
操作,而此宏是
O(N)
),以及数组中每个对象的元素,因为您事先不知道哪些字段位于哪个对象中。

非常感谢
cJSON\u ArrayForEach
位。不过,我有一个疑问,如果我想让它完全动态化,以备将来使用,
elem->valueint
将不起作用。如果该值是一个字符串,并且像以前一样我不知道,那么如何以更通用的方式编写它,而不是使用
valueint
?我每次都需要做
elem->type
检查吗?@rb-93有一些函数用于检查值是否是字符串、数字等。在健壮的代码中应该首先检查这些值,是的。关于您编写的内容,我有一个问题。“简单的方法是将if/else if和strcmp()组合在一起。”。我在某个地方读到,在C语言中,我无法检查结构成员是否存在。这就是为什么我必须用
if/else
检查每个成员的原因吗?我脑海中突然出现的另一个问题是,我是否可以用
elem->string
elem->valueint
填充
char*argv[]
来模拟在获取命令行参数时使用的
char*argv[]