Using a #define in a formatted printf to define precision

1k views Asked by At
#include <stdio.h>
#define PREC 4

int main()
{
    long l = 12;
    printf("%PRECld", l);
}

How would I be able to use PREC to define the precision wanted? i.e. the expected output would be 0012. Currently printing %PRECld.

3

There are 3 answers

0
ShadowRanger On BEST ANSWER

To expand the macro to make it part of a compile time format string, you'll need a stringification macro (yes, the two layers are necessary; if you only defined #define STR(x) #x, STR(PREC) would insert the string "PREC", not "4" as you want):

#define _STR(x) #x
#define STR(x) _STR(x)

Then you can use it like so:

printf("%0" STR(PREC) "ld", l);

That will be expanded by the preprocessor to:

printf("%0" "4" "ld", l);

and since adjacent string literals are treated as a single string, it ends up compiling as if you directly typed:

printf("%04ld", l);

For a runtime solution, you use * to set precision dynamically from an argument, with no need for a stringification macro:

printf("%0*ld", PREC, l);

In theory, this is slightly slower at runtime, since it needs to parse a more complex format string, pass and receive more arguments, etc., but in practice I/O is so expensive that the cost of a little CPU fiddling is trivial in comparison.

Note the added 0 in both versions, to make it pad with zeroes, not spaces.

0
tadman On

Pretty straightforward:

int main()
{
    long l = 12;
    printf("%*ld", PREC, l);

    return 0;
}
0
ThenTech On

Just use the field width formatting as you normally would with *:

#include <stdio.h>
#define PREC 4

int main()
{
    long l = 12;
    printf("%*ld", PREC, l);   // "  12"
    printf("%0*ld", PREC, l);  // "0012"
}

See the printf reference and look for field width.