5

我有以下用于德语动词练习的代码块:

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];
4

2 回答 2

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));
于 2012-11-10T15:53:00.180 回答
4

您正在混合编译时和运行时选项。在 C 中,您不能直接从运行时获得的字符串中使用标识符。但是,您可以将您的比较带入一个不透明的函数中。

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);
于 2012-11-10T14:31:50.067 回答