1

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

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

        {
            "height": 16
        }
    ]
}

通过以下内容,我可以访问该text字段。

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 文件包含的内容,可以有更多参数,例如volume、等。area这个想法是我有一个struct包含所有这些参数的,我必须检查 JSON 中提供的参数是否存在并相应地设置值。struct看起来像:

typedef struct {
   char *path;
   int length;
   int width;
   int height;
   int volume;
   int area;
   int angle;
   int size;
} JsonParameters;

我试着这样做:

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);
}

这返回Memory access error (memory dumped)加上我必须说明什么是键。如前所述,我不知道参数是什么。

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

4

1 回答 1

2

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

#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;
}

您可以将每个字段名称与您关心的字段列表进行比较(简单的方法是一堆if/else ifstrcmp()),为每个字段设置结构的适当字段。

这里重要的是使用cJSON_ArrayForEach宏来遍历数组的两个元素(cJSON 将 JSON 数组表示为链表,并且像在您的代码中一样通过索引获取每个元素使得迭代数组成为一个O(N^2)操作,而这个宏是O(N)),并且数组中每个对象的元素,因为您事先不知道哪些字段在哪个对象中。

于 2019-11-13T14:48:02.177 回答