2017-05-30 13 views
0

以下のコードシーケンスを試しています...私の意図は、マクロの入力引数を数値として使用し、それをintとして扱う新しい文字列を生成することです連結します。それは文字列として扱っているように見えます。これを達成する方法はありますか?Cで正しく置換されないマクロへの引数

typedef enum 
{ 
    HELLO0BYE = 0, 
    HELLO1BYE = 1, 
    HELLO2BYE = 2, 
    HELLO3BYE = 3, 
    HELLO4BYE = 4, 
    HELLO5BYE = 5, 

} enum_test; 

#define GEN_NEW(x) HELLO ##x## BYE 
void main() 
{ 
    enum_test input = 5; 
    enum_test output; 
    output = GEN_NEW(input); 
} 

理想的には私はアルゴリズムの方法で、列挙型を反復処理することができるようにしたいです。

+2

'number'は前処理' stage'に値を持たない。これはプリプロセッサのトークンに過ぎません。 –

+1

出力の例を追加できますか? – BetaRunner

+1

マクロ拡張では識別子のようなトークンの間に '## 'が現れることに注意してください。最初の '## 'は誤りです。 –

答えて

2

私はあなたの質問を理解するので、あなたはできません。しかし、私はあなたが何をしようとしているのか完全にはわからないと思う。

マクロは前処理されています。つまり、コードがコンパイルされる前にマクロが置換されます。したがって、GEN_NEWマクロを使用すると、すべてのコンパイラが「数字」について知っているのは、それが文字列だということです。したがって、実行時変数をマクロに渡すことはできません。

希望に役立ちます。上記のコードは、コンパイラによって処理されると

1

、我々は出力を以下の取得:

# 1 "Test1.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "Test1.c" 
typedef enum 
{ 
    HELLO0BYE = 0, 
    HELLO1BYE = 1, 
    HELLO2BYE = 2, 
    HELLO3BYE = 3, 
    HELLO4BYE = 4, 
    HELLO5BYE = 5, 

} enum_test; 


void main() 
{ 
    enum_test input = 5; 
    enum_test output; 
    output = HELLOinputBYE; 
} 

あなたは上記のコードを見ると、あなたが次の行がエラー持っていることがわかります。

output = HELLOinputBYE; 

を注:前処理段階の後にコンパイラを停止するには、 '-E'スイッチを使用します。私は、GCCコンパイラで、次の使用:ここで

gcc -E -o TestPreprocessedFile.txt Test1.c 

「Test1.cには、」ソースファイルであり、「TestPreprocessedFile.txt」の出力ファイルです。 GCCコンパイラオプションの詳細については

Options Controlling the Kind of Output

0

を参照してください。私はあなたの実装の正確なロジックを知らないので、私はその議論に入ることはありません。

#define CONV2STRING(X) #X 
#define TO_STRING(X) CONV2STRING(X) 
#define EXPAND(Y) Y 
#define MERGER(X, Y) X##Y 
#define MERGE(X, Y) MERGER(X, Y) 

#define SAY_HELLO HELLO 
#define SAY_BYE BYE 

typedef enum { 
    HELLO0BYE = 0, 
    HELLO1BYE = 1, 
    HELLO2BYE = 2, 
    HELLO3BYE = 3, 
    HELLO4BYE = 4, 
    HELLO5BYE = 5, 
} enum_test; 

const static struct { 
    enum_test  value; 
    const char *str; 
} conversion [] = { 
    {HELLO0BYE, "HELLO0BYE"}, 
    {HELLO1BYE, "HELLO1BYE"}, 
    {HELLO2BYE, "HELLO2BYE"}, 
    {HELLO3BYE, "HELLO3BYE"}, 
    {HELLO4BYE, "HELLO4BYE"}, 
    {HELLO5BYE, "HELLO5BYE"}, 
}; 

int StringToEnum (const char *str) { 
    int j; 
    for (j = 0; j < sizeof (conversion)/sizeof (conversion[0]); ++j) 
     if (!strcmp (str, conversion[j].str)) 
      return conversion[j].value; 
    return -1; 
} 

int main(int argc, char** argv) 
{ 
    enum_test output; 

    #define INPUT 5 
    output = StringToEnum(TO_STRING (MERGE(MERGE(SAY_HELLO, EXPAND(INPUT)), SAY_BYE))); 
    printf("Macro Expansion : %s\n", TO_STRING (MERGE(MERGE(SAY_HELLO, EXPAND(INPUT)), SAY_BYE))); 
    printf("output = %d\n", output); 
    #undef INPUT 

    #define INPUT 4 
    output = StringToEnum(TO_STRING (MERGE(MERGE(SAY_HELLO, EXPAND(INPUT)), SAY_BYE))); 
    printf("Macro Expansion : %s\n", TO_STRING (MERGE(MERGE(SAY_HELLO, EXPAND(INPUT)), SAY_BYE))); 
    printf("output = %d\n", output); 
    #undef INPUT 
} 

注:私は、文字列から列挙hereにエレガントな変換を見つけたあなたはこれを使用することができます。

関連する問題