首页 > 解决方案 > 在静态结构实例中初始化和访问二维字符数组

问题描述

对于以下表结构,我可以创建一个静态表并打印值:

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

但是,如果我添加多个值,则无法创建静态表:

+------+-----------------------+
| 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"},
};

这给了我以下错误:

"Too many initializers"

我应该如何初始化和迭代它?

标签: arrayscpointersstruct

解决方案


使用作为 . 数组的复合文字char*

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

迭代有点复杂。我看到了三种策略:

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. 用 标记最后一个条目NULL

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

迭代:

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

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"),
  ...
};

此宏应用sizeof X / sizeof X[0]技巧来评估X数组元素的数量。它本质上是将数组的大小(以字节为单位)除以其单个元素的大小(也以字节为单位)。

在这种情况下,它是sizeof((char*[]){ ... }) / sizeof(char*)。可变参数宏用于处理键之后的所有宏参数。基本上,__VA_ARGS__替换为值字符串列表。


推荐阅读