2010-10-24 45 views
4

是否可以编写返回printf格式的宏(使用令牌串联)? 例如用于生成printf格式字符串的C宏

#define STR_FMT(x) ...code-here... 

STR_FMT(10)扩展到"%10s"

STR_FMT(15)扩展到"%15s"

... 等

所以,我可以用这个宏一个printf里面:

printf(STR_FMT(10), "*"); 

回答

12

可以,但我认为它可能是更好地使用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?中所述)。

+2

如果可以的话,我会赞成这两次。 – 2010-10-24 20:46:18

+1

+1提到'%*',并找出OP可能想要传递变量而不是编译时常量到这个宏。 – 2010-10-24 22:03:56

7
#define STR_FMT(x) "%" #x "s" 
+0

我会删除我的答案;) – AraK 2010-10-24 20:22:51