我正在用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"}}
};
我收到以下错误:
错误:初始化灵活 嵌套上下文中的数组成员
错误:(接近初始化 “标签[0] .message”)
如何在第二个示例中初始化制表符数组? 注意:我知道选项卡数组中的所有值。
更新:消息可以是不同的大小,例如
typedef struct {
char* action;
char* message[];
} lookuptab;
lookuptab tab[] = {
{"aaa", {"bbbb", "ccc", "dd"}},
{"cc", {"dd", "eeeee"}}
};
非常感谢。
祝你好运, 维克多
答案 0 :(得分:12)
您不能在数组(结构)中使用包含灵活数组成员的结构。见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编译器,请注意。
答案 1 :(得分:2)
我认为您必须指定数组大小才能在另一个数组中使用该结构:
typedef struct {
char* action;
char* message[2];
} lookuptab;
答案 2 :(得分:0)
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 <stdlib.h>
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;
}
答案 3 :(得分:0)
您需要在结构定义中指定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);
...
}
您可以使用sentinel:
,而不是明确传递消息数 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++;
}
}