cJSON 键值解析

cJSON Key-Value Parsing

我正在使用 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); 
}

注意:这些参数是动态的,因为可以有更多参数,例如 volumearea 等,具体取决于 JSON 文件包含的内容。我的想法是我有一个 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);
}

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

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

这是一个示例程序,它遍历示例 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;
}

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

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