2013-09-01 32 views
1

如何檢索從宏展開的文本?打印由預處理器形成的變量標識符

#include <stdio.h> 

#define paste(front, back) front ## back 

int main() 
{ 
    int number1 = 23; 
    int number2 = 64; 

    printf("%d\n", paste(number, 2)); 


    return 0; 
} 

的輸出是:因爲宏展開爲:

printf("%d\n", number2); 

如何可以通過使用所定義的糊宏打印標識符NUMBER2作爲字符串。我需要知道如何創建輸出: 數字2:64通過不直接寫「號碼2」 我不希望這個解決方案

printf("number2: %d\n", paste(number, 2)) 

我想要一個動態的解決方案。我嘗試做來連接:

printf("%s: %d\n", paste(number, 2), paste(number, 2)); 

但它不工作,因爲被貼宏返回數字2是一個標識符整數我如何可以檢索的文本(字符串)?

回答

2

使用字符串化指令#

#define stringize_impl(x) #x 
#define stringize(x) stringize_impl(x) 

printf("%s: %d\n", stringize(paste(number, 2)), paste(number, 2)); 

在一個側面說明:爲什麼你想這樣做嗎?當然必須有更好的解決方案。

+0

輸出是* paste(number,2):64 *問題是粘貼宏在使用前奏時未擴展字符串,但我不知道爲什麼。我正在使用gcc。我只是爲了學習的目的(在K&R書中解釋如何使用#來擴展宏參數作爲字符串)。 – Wronski

+0

@Wronski我使用clang在本地進行了測試,並使用IDEOne和GCC([link](http://ideone.com/g9QVJQ))。這是保證工作的標準(這裏是一個[相關問題](http://stackoverflow.com/questions/2751870/how-exactly-does-the-double-stringize-trick-work))。 – 2013-09-01 18:22:21

+0

@ H2CO3我猜Wronski正在這樣做,以查看宏是否以編程方式擴展。 –

2

如果您使用GCC進行編譯,您可以使用gcc -E filename.c來調用它以查看宏的擴展。

編輯:

您還可以使用stringize預處理程序操作#,有效地把周圍的右手符號雙引號。

#include <stdio.h> 

#define T(...) #__VA_ARGS__ 
#define paste(f, b) _paste(f, b) 
#define _paste(front, back) front##back 

int main() 
{ 
    int n = 5; 
    printf("macro expands to: '%s'\n", T(paste(number, 2), paste(number, 2))); 
    printf("macro expands to: '%s'\n", T(paste(n, 2))); 
    return 0; 
} 

此代碼希望能夠回答這個問題。

您需要再次展開宏來擴展字符串大小的粘貼。換句話說,對於要擴展的stringize宏中的paste宏,預處理器必須再次傳遞該文件。這就是爲什麼你將它傳遞給文件中稍後定義的另一個宏。

我不是100%確定預處理器的所有規則,但是這似乎很好。對於想要在另一個宏內擴展的每個宏,需要做一些魔法來強制預處理器再次傳遞文件:)根據我的知識,存在實現此目的的不同方法,但這是一種方法。

EDIT2:

編輯的代碼。我得到這個輸出,這是你想要的嗎?

[email protected]:/tmp$ ./a.out 
macro expands to: 'paste(number, 2), paste(number, 2)' 
macro expands to: 'paste(n, 2)' 
+0

我無法使它工作。我認爲你的解決方案是正確的,但是當我運行宏不擴展時,你測試它嗎? – Wronski

+0

當粘貼到這裏時發生了什麼:)這顯示了宏展開的內容。這是你想要的嗎? –

+0

Nope:P我想要簡單的輸出* number2:64 *作爲@ H2CO3解決方案。 – Wronski