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 に答える