Макрос C для генерации строки формата printf - PullRequest
4 голосов
/ 25 октября 2010

Можно ли написать макрос (с использованием конкатенации токенов), который возвращает формат для printf?Например,

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

STR_FMT(10) расширяется до "%10s"

STR_FMT(15) расширяется до "%15s"

... и т. Д.

Итакчто я могу использовать этот макрос внутри printf:

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

Ответы [ 2 ]

12 голосов
/ 25 октября 2010

Можно, но я думаю, что было бы лучше использовать возможность 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"

В противном случае, если вы решите использовать макросы для указания ширины поля, вы получите нежелательное поведение (как описано в Какие приложения оператора ## препроцессора и какие ошибки следует учитывать? ).

7 голосов
/ 25 октября 2010
#define STR_FMT(x) "%" #x "s"
...