繁体   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-2024 STACKOOM.COM