简体   繁体   English

初始化和访问 static 结构实例中的二维字符数组

[英]Initialize and access 2D char array in static structure instance

For following table structure, I could create a static table and print the values:对于以下表结构,我可以创建一个 static 表并打印值:

+------+---------+
| key1 |  value1 |
| key2 |  value2 |
| key3 |  value3 |
+------+---------+

#include <stdio.h>

typedef struct key_value_map
{
  char *key;
  char *value;
} KeyValueMap;

static KeyValueMap key_value_map_table[] =
{
  {"key1", "value1"},
  {"key2", "value2"},
  {"key3", "value3"},
};

int main(void) {
    int i = 0;
    int n = sizeof(key_value_map_table)/sizeof(key_value_map_table[0]);
    for(i=0; i<n; ++i)
    {
        printf("Key=%s, Val=%s\n",key_value_map_table[i].key, 
                                  key_value_map_table[i].value);
    }
    return 0;
}

However, if I add more than one values then I'm not able to create a static table:但是,如果我添加多个值,则无法创建 static 表:

+------+-----------------------+
| key1 |  value1 value2 value3 |
| key2 |  value1 value4 value5 |
| key3 |  value2 value4        |
| key4 |  value5               |
+------+-----------------------+

typedef struct key_values_map
{
  char *key;
  char **values;
}KeyValuesMap;

static KeyValuesMap key_values_map_table[] =
{
  {"key1", "value1", "value2", "value3"},
  {"key2", "value1", "value4", "value5"},
  {"key3", "value2", "value4"},
  {"key3", "value5"},
};

This is giving me following error:这给我以下错误:

"Too many initializers"

How should I initialize and iterate over it?我应该如何初始化和迭代它?

Use compound literals that are arrays of char* .使用char*的 arrays 的复合文字。

static KeyValuesMap key_values_map_table[] =
{
  {"key1", (char*[]){"value1", "value2", "value3"}},
  {"key2", (char*[]){"value1", "value4", "value5"}},
  {"key3", (char*[]){"value2", "value4"}},
  {"key3", (char*[]){"value5"}},
};

Iteration is bit more complex.迭代有点复杂。 I see three strategies:我看到三种策略:

A. Use explicit length: A. 使用显式长度:

typedef struct key_values_map {
  char *key;
  size_t count;
  char **values;
}KeyValuesMap;

static KeyValuesMap key_values_map_table[] = {
  {"key1", 3, (char*[]){"value1", "value2", "value3"}},
  ...
};

B. Mark the last entry with NULL . B. 用NULL标记最后一个条目。

{"key1", (char*[]){"value1", "value2", "value3", NULL}},

Iterate with:迭代:

for (char **p = key_values_map_table[0].values; *p; ++p) {
  char *str = *p;
  ...
}

C. Use a macro to infer size for A variant. C。使用宏推断 A 变体的大小。

#define MK_ENTRY(key, ...)                            \
  { key,                                              \
    sizeof((char*[]){ __VA_ARGS__ }) / sizeof(char*), \
    (char*[]){ __VA_ARGS__ } }

static KeyValuesMap key_values_map_table[] = {
  MK_ENTRY("key1", "value1", "value2", "value3"),
  ...
};

This macro applies sizeof X / sizeof X[0] trick to evaluate the number of elements of X array.这个宏应用sizeof X / sizeof X[0]技巧来评估X数组的元素数量。 It essentially divides the size of array (in bytes) by the size of its single element (in bytes as well).它本质上是将数组的大小(以字节为单位)除以其单个元素的大小(也以字节为单位)。

In this case it is sizeof((char*[]){... }) / sizeof(char*) .在这种情况下,它是sizeof((char*[]){... }) / sizeof(char*) A variadic macro is used to handle all macro arguments after the key.可变参数宏用于处理键后的所有宏 arguments。 Basically, __VA_ARGS__ is replaced by the list of the value strings.基本上, __VA_ARGS__被值字符串列表所取代。

You may create an array for each key to list the values associated with that key, then include the array identifiers in the table initializer where appropriate.您可以为每个键创建一个数组以列出与该键关联的值,然后在适当的地方将数组标识符包含在表初始值设定项中。

An example of how this could be done:如何做到这一点的一个例子:

    const char * key1_vals[] = {"value1", "value2", "value3"};
    const char * key2_vals[] = {"value1", "value4", "value5"};
    const char * key3_vals_1[] = {"value2", "value4"};
    const char * key3_vals_2[] = {"value5"};

    static KeyValuesMap key_values_map_table[] =
    {
        {"key1", key1_vals},
        {"key2", key2_vals},
        {"key3", key3_vals_1},
        {"key3", key3_vals_1},
    };

Some things to keep in mind:一些事情要记住:

  1. You will need to keep track of the number of values associated with each key in object KeyValueMap, so that the program knows how many values to look for.您将需要跟踪与 object KeyValueMap 中每个键关联的值的数量,以便程序知道要查找多少个值。
  2. You may want to replace char *key;您可能想要替换char *key; and char *value;char *value; with const char *key;const char *key; and const char *value;const char *value; so that the program knows that these pointers are pointing to constant data.这样程序就知道这些指针指向常量数据。

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

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