2010-10-24 53 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