是否可以编写一个使用令牌连接的宏,以返回printf的格式? 例如:
#define STR_FMT(x) ...code-here...
STR_FMT(10)
扩展为 "%10s"
STR_FMT(15)
扩展为 "%15s"
... 等等。
因此,我可以在printf中使用这个宏:
printf(STR_FMT(10), "*");
是否可以编写一个使用令牌连接的宏,以返回printf的格式? 例如:
#define STR_FMT(x) ...code-here...
STR_FMT(10)
扩展为 "%10s"
STR_FMT(15)
扩展为 "%15s"
... 等等。
因此,我可以在printf中使用这个宏:
printf(STR_FMT(10), "*");
你可以这样做,但我认为最好使用 printf()
功能来动态指定字段大小和/或精度:
#include <stdio.h>
int main(int argc, char* argv[])
{
// specify the field size dynamically
printf( ":%*s:\n", 10, "*");
printf( ":%*s:\n", 15, "*");
// specify the precision dynamically
printf( "%.*s\n", 10, "******************************************");
printf( "%.*s\n", 15, "******************************************");
return 0;
}
这样做的好处是不使用预处理器,您还可以使用变量或函数来指定字段宽度而不是字面值。
如果您决定改用宏,请间接使用 #
运算符(如果在其他地方使用了 ##
运算符,则也使用它),方法如下:
// macros to allow safer use of the # and ## operators
#ifndef STRINGIFY
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#endif
#define STR_FMTB(x) "%" STRINGIFY(x) "s"
否则,如果您决定使用宏来指定字段宽度,您将得到不希望的行为(如What are the applications of the ## preprocessor operator and gotchas to consider?中所述)。
#define STR_FMT(x) "%" #x "s"
printf
替换被视为不安全的,因为宏参数的错误会导致易受内存布局攻击的二进制代码。 - Byron Hawkins
%*
,并且明白OP可能想要将变量而不是编译时常量传递给这个宏。 - R.. GitHub STOP HELPING ICE