打印与变量相关联的宏标识符的名称

问题描述:

我找不到与此类似的内容。现在打印与变量相关联的宏标识符的名称

#define ONE 1 
#define TWO 2 

int main() 
{ 
    int x = ONE; 
    printf("%s \n", x); 
} 
//the desirable output will be "ONE" 

,我看到与

#define PRINT(X) printf("%s \n", #x); 

其他的答案,我怎么没发现用它来得到我想要的东西。

+1

难道你不是将1定义为1吗?所以你可以说x = ONE;它会和你现在正在做的一样吗? – matt

+1

你想完成什么?如何阅读'printf'的文档?如果这没有帮助,也许你会错过这门语言的一些基础知识。上面的代码调用未定义的行为,Iow:它不是有效的C. – Olaf

+1

'//例外的输出将是“ONE”'你确定吗?你尝试过吗? – Karthick

正如@KeithThompson所说,没有简单的方法。

但是有一个clever hack它或多或少地做你所要求的。

#define MY_ENUM_LIST \ 
    X(ONE , 1) \ 
    X(TWO , 2) \ 
    X(THREE , 3) 

#define X(name, value) name = value, 
enum MyEnum {MY_ENUM_LIST}; 
#undef X 

const char *my_enum_to_str(enum MyEnum e) 
{ 
    switch (e) 
    { 
     #define X(name, value) case value: return #name; 
     MY_ENUM_LIST 
     #undef X 
     default: 
     return "<invalid>"; 
    } 
} 

int main() 
{ 
    int x = ONE; 
    printf("%d\n", x); // prints "1" 
    printf("%s\n", my_enum_to_str(x)); // prints "ONE" 

    return 0; 
} 

它具有以下优点在天真的查找表:

  • 没有必要重复枚举的名字两次。
  • 您可以拥有任何枚举值,而不仅仅是连续的范围。
  • 您不能意外地将一个不正确的名称分配给一个枚举器。
+0

完美!谢谢!!!!!!! –

+0

这是一个可怕的方法。 – Olaf

+0

@Olaf请详细说明。说“糟糕的做法”根本没有建设性。 AFAIK它是最好的现有解决方案。唯一的选择是简单的查找表(它需要重复枚举器名称,通常会导致错误),并在运行时通过名称查找枚举值,这显然很慢。这种方法唯一的缺点是语法非常奇特。 – HolyBlackCat

没有直接的方法来做到这一点。您在printf调用中唯一的信息是变量x,其当前值恰好为1(运行时),这恰好是名称为ONE的宏的扩展。编译器无法从该信息中找出名称ONE。可能有几个具有相同定义的不同宏,或者可能没有任何宏。

如果你想打印字符串ONE给定的整数值1,你将不得不建立某种查找表或函数。例如:

const char *const names[] = { "ZERO", "ONE", "TWO", "THREE", "FOUR", /* etc. */ }; 
printf("%s\n", names[x]); 

这将是完全取决于你得到的姓名权,从而例如1不映射到"THREE"

+0

谢谢你,很棒的解决方案!但要叫它让我努力工作。 @HolyBlackCat的答案对我来说更好。谢谢! –

+2

我也会创建数组'const'。 – Olaf

+0

@Olaf:好的,完成了。 –