[英]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.