cJSON键值解析

时间:2019-11-13 14:05:20

标签: c json cjson

我正在使用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文件包含的内容,可以有更多的参数,例如volumearea等。这个想法是我有一个包含所有这些参数的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中的有效参数检查键?

1 个答案:

答案 0 :(得分:1)

这是一个示例程序,它从示例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^2)时进行{1}}操作,以及数组中每个对象的元素,因为您无法提前知道哪个字段位于哪个对象中。