2017-05-30 33 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'在预处理阶段没有值。这只是一个预处理器的标志。 –

+1

你能添加一个你想要的输出的例子吗? – BetaRunner

+1

请注意'##'应该出现在宏扩展中的标识符标记之间。第一个##是错误的。 –

回答

2

据我了解你的问题,不,你不能。但我怀疑我不完全确定你在做什么。

宏的预处理。这意味着在您的代码被编译之前,宏的get取代。所以当你使用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