簡體   English   中英

在 C 中的 printf 字符串中使用宏?

[英]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 視為特殊字符串,並且不會將我的宏放入字符串中。 有沒有辦法實現我想要的?

使用簡單的數字如 arguments 進行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);

使用宏作為 arguments 進行格式化

有沒有辦法將我的 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.

 
粵ICP備18138465號  © 2020-2025 STACKOOM.COM