我有以下用于德语动词练习的代码块:
if (strcmp(*option, "sein") == 0)
*option = linie.sein;
if (strcmp(*option, "haben") == 0)
*option = linie.haben;
if (strcmp(*option, "possessiv") == 0)
*option = linie.possessiv;
if (strcmp(*option, "reflexiv") == 0)
*option = linie.reflexiv;
if (strcmp(*option, "accusativ") == 0)
*option = linie.accusativ;
if (strcmp(*option, "dativ") == 0)
*option = linie.dativ;
但是我想把它浓缩成类似的东西:
*option = linie.(*option);
或者也许:
*option = linie.(*option)();
不幸的是,这些都不起作用。有什么想法吗?
编辑@dasblinkenlight:
typedef struct
{
char subjekt[20];
char sein[20];
char haben[20];
char possessiv[20];
char reflexiv[20];
char accusativ[20];
char dativ[20];
} satz;
satz linie =
{
.subjekt = "",
.sein = "",
.haben = "",
.possessiv = "",
.reflexiv = "",
.accusativ = "",
.dativ = ""
};
char *option = argv[1];
答案 0 :(得分:5)
基里连科的答案很好,适用于像你这样的短型结构。但是,对于较长的结构,维护所有strcmp调用可能很麻烦。要解决此问题,您可以定义要匹配的关键字与结构中相应元素的偏移量之间的关系。
struct relation
{
char keyword[20];
int offset;
};
然后你可以使用offsetof宏(在stddef.h中)将关键字链接到它在结构中的位置。
#define REL_LEN (7)
struct relation rel[REL_LEN] = {
{"subjekt", offsetof(satz, subjekt) },
{"sein", offsetof(satz, sein) },
{"haben", offsetof(satz, haben) },
{"possessiv", offsetof(satz, possessiv) },
{"reflexiv", offsetof(satz, reflexiv) },
{"accusativ", offsetof(satz, accusativ) },
{"dativ", offsetof(satz, dativ) }
};
最后,使用上面的映射检索字符串的函数可能看起来像这样。
char *lookup_keyword(const satz *linie, const char *option,
const struct relation *rel, size_t rel_size)
{
int i;
char *pchar = (char *)linie;
for (i=0; i<rel_size; i++)
{
if (strcmp(option, rel->keyword) == 0)
{
pchar += rel->offset;
return pchar;
}
rel++;
}
printf("Error: no mapping found matching %s!\n", option);
return "";
}
你可以像这样调用它
char *option = argv[1];
printf("Result for %s: %s\n", option,
lookup_keyword(&linie, option, rel, REL_LEN));
答案 1 :(得分:4)
您正在混合编译时和运行时选项。在C中,您不能直接从运行时获得的字符串中使用标识符。但是,您可以将您的comparaisons带入不透明的功能。
char *f(const satz *linie, const char *option)
{
if (strcmp(option, "sein") == 0)
return linie->sein;
else if (strcmp(option, "haben") == 0)
return linie->haben;
else if (strcmp(option, "possessiv") == 0)
return linie->possessiv;
else if (strcmp(option, "reflexiv") == 0)
return linie->reflexiv;
else if (strcmp(option, "accusativ") == 0)
return linie->accusativ;
else if (strcmp(option, "dativ") == 0)
return linie->dativ;
else
return NULL;
}
*option = f(&linie, *option);