C中的动态代码

时间:2012-11-10 14:12:28

标签: c dynamic

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

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

2 个答案:

答案 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);