[英]Using macros inside a printf string in C?
給定 3 個雙打 x、y 和 z,我進行了很多這樣的 printf 調用:
printf("[%+-8.3lf, %+-8.3lf, %+-8.3lf]\n", x, y, z);
然后我想有一個宏來寫這樣的東西:
#define FORMAT(x,y) "+-x.ylf"
printf("[%FORMAT(8,3), %FORMAT(8,3), %FORMAT(8,3)]\n", a->x, a->y, a->z);
但當然,編譯器將 %F 視為特殊字符串,並且不會將我的宏放入字符串中。 有沒有辦法實現我想要的?
FORMAT
您的“類似這樣”的代碼很接近 - 但您需要使用字符串連接(相鄰字符串文字)和#
運算符來“字符串化”宏 arguments:
#define FORMAT(x,y) "%+-" #x "." #y "lf"
printf("[" FORMAT(8,3) ", " FORMAT(8,3) ", " FORMAT(8,3) "]\n",
a->x, a->y, a->z);
這類似於使用<inttypes.h>
中的宏來打印類型,例如int64_t
,除了那些,你必須提供%
符號(和任何標志):
uint64_t x = 0x43218765CBA9;
printf("x = 0x%.12" PRIX64 "\n", x);
有沒有辦法將我的 8 和 3 值也定義為宏? 我不想到處寫
FORMAT(8,3)
,而是想在上面定義的地方寫FORMAT(X, Y)
#define X 8
和#define Y 3
。
是的,有辦法做到這一點。 引入一個額外的宏:
#define STR(z) #z
並在 arguments 上將其調用為FORMAT
,如下所示:
/* SO 7531-4669 */
#include <stdio.h>
#define STR(z) #z
#define FORMAT(x,y) "%+-" STR(x) "." STR(y) "lf"
#define Y 4
#define X 8
struct Point { double x, y, z; };
int main(void)
{
struct Point b = { 7123.4567, 6234.5678, 5345.6789 };
struct Point *a = &b;
printf("[" FORMAT(X, Y) ", " FORMAT(X, Y) ", " FORMAT(X, Y) "]\n",
a->x, a->y, a->z);
printf("[" FORMAT(8, 3) ", " FORMAT(8, 3) ", " FORMAT(8, 3) "]\n",
a->x, a->y, a->z);
return 0;
}
這有效並產生 output:
[+7123.4567, +6234.5678, +5345.6789]
[+7123.457, +6234.568, +5345.679]
它演示了您可以使用簡單數字或宏,即 map 到簡單數字,如 arguments 到此FORMAT
宏。 您不能做的是#define Y 3
和#define X (Y + 6)
— 這將對(3 + 6)
進行字符串化,這在printf()
轉換規范中是無效的。 (注意不要讓X
太大;你的數字和后面的逗號之間可能會有空格。 #define X 12
看看我的意思。)
調用另一個宏的技術會觸發參數的擴展,這通常是您想要的。 請參閱如何從 C 宏的值生成 char 字符串? 和C 中的宏指令 — 我的代碼示例不起作用。 問答如何使用 C 預處理器連接兩次並擴展宏,如“ arg ## _ ## MACRO
”? 是關於令牌連接而不是字符串化,但問題密切相關,解決方案相似。
您可以將宏調整為:
#define SPEC "lf"
#define FORMAT(x, y) "+-"#x"."#y SPEC
並致電printf
:
printf("%"FORMAT(3, 20), x)
將%
放在宏中也可能是個好主意。
單個 hash (#),將 x 和 y arguments “轉換”為字符串文字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.