C中的动态代码

use*_*643 5 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;
Run Code Online (Sandbox Code Playgroud)

但是我想把它浓缩成类似的东西:

*option = linie.(*option);
Run Code Online (Sandbox Code Playgroud)

也许:

*option = linie.(*option)();
Run Code Online (Sandbox Code Playgroud)

不幸的是,这些都不奏效.有任何想法吗?

编辑@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];
Run Code Online (Sandbox Code Playgroud)

小智 5

基里连科的答案很好,适用于像你这样的短型结构.但是,对于较长的结构,维护所有strcmp调用可能很麻烦.要解决此问题,您可以定义要尝试匹配的关键字与结构中相应元素的偏移量之间的关系.

struct relation
{
    char keyword[20];
    int offset;
};
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用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) }
};
Run Code Online (Sandbox Code Playgroud)

最后,使用上面的映射检索字符串的函数可能看起来像这样.

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 "";
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样调用它

char *option = argv[1];

printf("Result for %s: %s\n", option, 
       lookup_keyword(&linie, option, rel, REL_LEN));
Run Code Online (Sandbox Code Playgroud)


md5*_*md5 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);
Run Code Online (Sandbox Code Playgroud)