简体   繁体   English

cJSON 键值解析

[英]cJSON Key-Value Parsing

I am using cJSON to parse a JSON stored in testdata.json file which looks like this:我正在使用 cJSON 解析存储在testdata.json文件中的 JSON 文件,如下所示:

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

        {
            "height": 16
        }
    ]
}

With the following I can access the text field.通过以下内容,我可以访问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); 
}

Note: These parameters are dynamic in the sense that there can be more parameters such as volume , area , etc depending upon what the JSON file contains.注意:这些参数是动态的,因为根据 JSON 文件包含的内容,可以有更多参数,例如volumearea等。 The idea is that I have a struct containing all these parameters and I have to check whether the parameters provided in the JSON exists or not and set the values accordingly.这个想法是我有一个包含所有这些参数的struct ,我必须检查 JSON 中提供的参数是否存在并相应地设置值。 The struct looks like: struct看起来像:

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

I tried to do it like this:我试着这样做:

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

This returns Memory access error (memory dumped) plus I have to state what are the keys.这将返回Memory access error (memory dumped)加上我必须 state 是什么键。 As mentioned, I cannot know what will be the parameters.如前所述,我不知道参数是什么。

How can I store the key-value pairs ( "length":10 , "width":16 , "height":16 etc) and how can I check the keys against the valid parameters in JsonParameters ?如何存储键值对( "length":10"width":16"height":16等)以及如何根据JsonParameters中的有效参数检查键?

Here's an example program that walks all the elements of the parameters array from your sample JSON, and prints out the names of the fields of each object in the array:这是一个示例程序,它从示例 JSON 中遍历parameters数组的所有元素,并打印出数组中每个 object 的字段名称:

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

You can compare each field name against a list of the ones you care about (The easy way is as a bunch of if / else if 's and strcmp() ), setting the appropriate field of your struct for each one.您可以将每个字段名称与您关心的字段列表进行比较(简单的方法是一堆if / else ifstrcmp() ),为每个字段设置适当的结构字段。

The important thing here is using the cJSON_ArrayForEach macro to walk both the elements of the array (cJSON represents JSON arrays as linked lists, and getting each element by index like in your code makes iterating through the array an O(N^2) operation while this macro is O(N) ), and the elements of each object in the array, since you don't know ahead of time which fields are in which object.这里重要的是使用cJSON_ArrayForEach宏来遍历数组的两个元素(cJSON 表示 JSON arrays 作为链表,并像在代码中一样通过索引获取每个元素使得遍历数组成为O(N^2)操作,同时这个宏是O(N) ),以及数组中每个 object 的元素,因为您事先不知道哪些字段在哪个 object 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM