2017-04-18 75 views
0

我找不到與此類似的內容。現在打印與變量相關聯的宏標識符的名稱

#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

回答

0

正如@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

5

沒有直接的方法來做到這一點。您在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:好的,完成了。 –