2015-11-05 88 views
2

MY_PRINT是整個代碼中的一個宏,它只是執行printf。 我想臨時修改它以在每個printf後追加\ n。如何創建一個C宏來爲每個printf添加/ n

然而,當我這樣做:

#define SENS_PRINT(x)  printf(x); printf("\n") 
MY_PRINT("\n #%d: %c ", ++command_line_number, sensor_operation_code); 

...輸出是垃圾:#3405240: <alpha symbol>

這將打印好的,但沒有\ n月底:

#define SENS_PRINT printf 
+0

事情是這樣的,printf需要可變數量的參數,當你使用(x)時你沒有考慮到這個參數,所以我認爲這個方案不會起作用 – kcraigie

+0

只是一個常識的呼叫:究竟是什麼是你首先想用'#define MY_PRINT printf'解決的問題嗎? – Lundin

回答

3

您希望您的宏能夠採用各種參數,就像真正的printf一樣。你可以用variadic宏來做到這一點。

還有一種危險是,當宏是條件代碼塊中唯一的表達式時,兩個單獨的表達式不會被解釋爲宏所示。想想如果你說if (flag) SENS_PRINT(...);宏是什麼。防止這種情況的一種方法是將宏包裝在do { ... } while(0)塊中。

是追加一個換行符printf可能看起來像這樣的可變參數宏:

#define PRINTFLN(...) do { printf(__VA_ARGS__); puts(""); } while (0) 

您可以使用它,就像printf

PRINTFLN("Hello %s!", "cruel world"); 
if (flag) PRINTFLN("%d + %d == %d", x, y, sum); 
1

的函數行宏的問題在於,預處理將所有逗號分隔的參數視爲宏的參數,而不是作爲單個參數。所以你的編譯器應該抱怨你傳遞給宏的許多參數。

一個簡單的解決方案是爲包圍宏參數括號中:

MY_PRINT(("\n #%d: %c ", ++command_line_number, sensor_operation_code)); 
//  ^                ^
//  |                 | 
// Note extra parentheses here...          and here 

另一種解決方案是使用variadic macros


在某種程度上相關的說明中,您的宏,如您所示,不能用於像例如。

if (some_condition) 
    MY_PRINT(...); 

將被替換像

if (some_condition) 
    printf(...); 
printf(...); 

如果你有一個宏內部多條語句,你需要把它們放在一個塊,例如像

#define MY_PRINTF(...) \ 
    do {    \ 
     statement1; \ 
     statement2; \ 
     .    \ 
     .    \ 
     .    \ 
     statementN; \ 
    } while (0) 
1

C語言可以讓您連接分隔字符串文字空白。如果您對MY_PRINT的所有調用都使用字符串作爲格式參數,則可以定義一個可變宏,它將直接將"\n"附加到您的格式字符串,然後應用其餘的參數。

定義宏像這樣

#define MY_PRINT(format, ...) printf(format "\n", __VA_ARGS__) 

你就能換行直接追加到格式化參數。

使用此方法只會執行一個函數調用,但使用除字符串常量之外的任何格式化的任何調用都會導致編譯錯誤。

+0

這種方法的缺點是,如果僅僅使用格式字符串調用它,比如'MY_PRINT(「沒有任何參數的字符串),它會失敗,因爲__VA_ARGS__會擴展爲'',導致語法錯誤(在確認平臺上)。 – BeeOnRope

相關問題