c中的查找表

我在C中创建一个查找表当我定义它时:

typedef struct { char* action; char* message; } lookuptab; lookuptab tab[] = { {"aa","bb"}, {"cc","dd"} }; 

它编译没有错误,但当我做这样的事情:

 typedef struct { char* action; char* message[]; } lookuptab; lookuptab tab[] = { {"aaa", {"bbbb", "ccc"}}, {"cc", {"dd", "eeeee"}} }; 

我收到以下错误:

错误:在嵌套上下文中初始化灵活数组成员

错误:(接近初始化’tab [0] .message’)

如何在第二个示例中初始化选项卡数组? 注意:我知道选项卡数组中的所有值。

更新:消息可以是不同的大小,例如

 typedef struct { char* action; char* message[]; } lookuptab; lookuptab tab[] = { {"aaa", {"bbbb", "ccc", "dd"}}, {"cc", {"dd", "eeeee"}} }; 

非常感谢你。

最好的问候,维克多

您不能在数组(结构)中使用包含灵活数组成员的结构。 见C99标准§6.7.2.1/ 2:

结构或联合不应包含具有不完整或函数类型的成员(因此,结构不应包含其自身的实例,但可以包含指向其自身实例的指针),除了结构的最后一个成员具有多个一个命名成员可能有不完整的数组类型; 这样的结构(以及可能递归地包含这种结构的成员的任何联合)不应是结构的成员或数组的元素。

因此,请使用char ** (并担心如何知道有多少条目):

 typedef struct { const char *action; const char * const *message; } lookuptab; static const lookuptab tab[] = { { "aaa", (const char * const []){ "bbbb", "ccc" } }, { "cc", (const char * const []){ "dd", "eeeee" } } }; 

这使用C99构造(§6.5.2.5复合文字) – 请注意,如果您不使用C99编译器。

我认为你必须指定数组大小才能在另一个数组中使用struct:

 typedef struct { char* action; char* message[2]; } lookuptab; 

您需要在结构定义中指定message数组成员的大小:

 #define N ... // maximum number of elements in message array typedef struct { char *action; char *message[N]; } lookuptab; lookuptab tab[] = { {"aa", {"bb", "cc"}}, {"dd", {"ee", "ff"}}, ... }; 

在这种情况下,N必须至少为2。

如果您希望lookuptab结构的每个实例在message数组中具有不同数量的元素,那么您将必须分别分配每个message数组,这意味着您将无法使用静态初始化程序:

 typedef struct { char *action; char **messages; } lookuptab; lookuptab *newEntry(const char *action, size_t numMessages, ...) { lookuptab *entry = malloc(sizeof *entry); if (entry) { entry->action = malloc(strlen(action) + 1); if (entry->action) strcpy(entry->action, action); if (numMessages > 0) { entry->messages = malloc(sizeof *entry->messages * numMessages); if (entry->messages) { size_t i; va_list ap; va_start(ap, numMessages); for (i = 0; i < numMessages; i++) { char *nextMessage = va_arg(ap, char *); entry->messages[i] = malloc(strlen(nextMessage) + 1); if (entry->messages[i]) strcpy(entry->messages[i], nextMessage); } } } } return entry; } int main(void) { lookuptab *tab[ENTRIES]; // for some number of ENTRIES tab[0] = newEntry("AA", 2, "BB", "CC"); tab[1] = newEntry("DD", 3, "EE", "FF", "GG"); tab[2] = newEntry("HH", 0); ... } 

您可以使用哨兵,而不是明确传递消息数量:

  tab[0] = newEntry("AA", "BB", "CC", NULL); 

但你要么必须循环遍历所有参数两次(首先要获取数字以分配messages数组,然后复制每条消息),否则你必须为每条消息重新分配realloc()数组,例如:

 size_t numMessages = 0; ... char *nextMessage while ((nextMessage = va_arg(ap, char *)) != NULL) { char **tmp = realloc(entry->messages, sizeof *entry->messages, numMessages+1); if (tmp) { entry->messages = tmp; entry->messages[numMessages] = malloc(strlen(nextMessage) + 1); strcpy(entry->messages[numMessages], nextMessage); numMessages++; } } 
 typedef struct { char* action; char* message[]; } lookuptab; 

lookuptab是一个不完整的类型。 您无法创建该类型的对象。 为消息数组提供确定的大小

 typedef struct { char* action; char* message[42]; } lookuptab_definite_size; 

或者使用四处指针并“手动”管理内存

 typedef struct { char* action; char** message; } lookuptab_pointers_all_around; 

你可以使用灵活的数组成员(所有元素将具有相同的大小),但它是很多工作:-)

 #include  typedef struct { char* action; char* message[]; } lookuptab; int main(void) { lookuptab *tab; tab = malloc(sizeof *tab + 42 * sizeof *tab->message); /* tab = malloc(elems * (sizeof *tab + 42 * sizeof *tab->message)); */ /* tab[0] ... tab[elems-1] all have the same size */ if (tab) { tab->action = NULL; tab->message[0] = NULL; tab->message[1] = NULL; /* ... */ tab->message[41] = NULL; free(tab); } return 0; }