# Thread: [C99] Using defined constant in a printf's format

1. Spilled the Beans
Join Date
Oct 2013
Beans
17

## [C99] Using defined constant in a printf's format

Hi,

I was wondering if it is possible to use a defined constant, like
Code:
`#define PRECISION 3`
In a printf format, like
Code:
`printf("%.PRECISIONf", SomeFloatVariable);`
How to define a number's precision by a constant?

2. Staff Emeritus
Join Date
Apr 2012
Beans
7,183

## Re: [C99] Using defined constant in a printf's format

You can specify the precision as an extra argument using '*' instead of the actual width e.g.

Code:
`printf("%.*f\n", PRECISION, floatval);`
There's a variant that allows you to use a numbered argument [CORRECTED (I hope) - thanks Bachstelze!] e.g.

Code:
`printf("%1\$.*4\$f %2\$.*5\$f %3\$.*4\$f\n", floatval, floatval, floatval, PRECISION, PRECISION_ALT);`
Code:
```#include <stdio.h>

#define M_PI 3.14159265358979323846264338327

#define PRECISION 3
#define PRECISION_ALT 6

int main()
{
printf("%.*f\n", PRECISION, M_PI);

printf("%1\$.*4\$f %2\$.*5\$f %3\$.*4\$f\n", M_PI, M_PI, M_PI, PRECISION, PRECISION_ALT);

return 0;
}```
Code:
```\$ gcc -std=c99 -Wall -o prec prec.c
\$
\$ ./prec
3.142
3.142 3.141593 3.142
\$```
- see the printf man page (man 3 printf)
Last edited by steeldriver; November 26th, 2013 at 11:40 PM.

3. ## Re: [C99] Using defined constant in a printf's format

You can take advantage of the automatic abuttal of string constants if PRECISION is a string literal (which make this more suitable for whole formats):

Code:
```#include <stdio.h>

#define FORMAT "%02x"

int main() {
}```
But in most cases you should be using a precision parameter as indicated above.

4. ## Re: [C99] Using defined constant in a printf's format

Originally Posted by steeldriver
although this throws a "missing \$ operand number in format [-Wformat]" warning for me it seems to work
I guess you should heed your own advice and read man 3 printf. The \$ construct is not standard, and also, if you use it at all, then you should use it everywhere.

5. Tall Cafè Ubuntu
Join Date
Feb 2009
Beans
1,468

## Re: [C99] Using defined constant in a printf's format

Another option
Code:
```#define STRINGIZE(x) #x
#define PRECISION 3
...
printf("%." STRINGIZE(PRECISION) "f", some_double);```
I'd normally prefer steeldriver's first suggestion though.

The %n\$ thing isn't just nonstandard; it's uncommon, and most C programmers have probably never heard of it, which means that unless it buys you something serious in clarity or performance, it's probably not worth the maintenance cost.

6. ## Re: [C99] Using defined constant in a printf's format

The things this format buys you is multi-language support, if the format string is a message to the user. Depending on language the substituted elements may not appear in the same order in the sentence.

7. Spilled the Beans
Join Date
Oct 2013
Beans
17

## Re: [C99] Using defined constant in a printf's format

Big thanks to you guys, I almost get it now. I just don't understand that "dollar" part. The beginning of the steeldriver's post seemed to solve my problem, but then this appeared:
Code:
`printf("%1\$.*4\$f %2\$.*5\$f %3\$.*4\$f\n", M_PI, M_PI, M_PI, PRECISION, PRECISION_ALT);`
Couldn't it be written in this way:
Code:
`printf("%.*f %.*f %.*f\n", PRECISION, M_PI, PRECISION_ALT, M_PI, PRECISION, M_PI);`
?
And, if we follow that dollar method, why isn't it in this way:
Code:
`printf("%1\$.*2\$f %1\$.*3\$f %1\$.*2\$f\n", M_PI, PRECISION, PRECISION_ALT);`
?

Also I wonder how that first one worked. For example:
Code:
`%1\$.*4\$f`
You give it first argument at the start, but it refers to the whole number to display not precision. A second "dollar" tells the precision but it's closer to the end of the format...
I'm not sure if you know what I mean. You can simply avoid that last question if you like
Last edited by ppplayer80; November 27th, 2013 at 05:02 PM.

8. ## Re: [C99] Using defined constant in a printf's format

Originally Posted by ppplayer80
Big thanks to you guys, I almost get it now. I just don't understand that "dollar" part. The beginning of the steeldriver's post seemed to solve my problem, but then this appeared:
Code:
`printf("%1\$.*4\$f %2\$.*5\$f %3\$.*4\$f\n", M_PI, M_PI, M_PI, PRECISION, PRECISION_ALT);`
Couldn't it be written in this way:
Code:
`printf("%.*f %.*f %.*f\n", PRECISION, M_PI, PRECISION_ALT, M_PI, PRECISION, M_PI);`
?
And, if we follow that dollar method, why isn't it in this way:
Code:
`printf("%1\$.*2\$f %1\$.*3\$f %1\$.*2\$f\n", M_PI, PRECISION, PRECISION_ALT);`
?
All of those do the same thing.

In general I will agree with trent.josephsen that the \$ construct does more harm than good. It's one of those things that seem to have been invented only to make a hacker's life easier (the only place I have ever seen it used in practice is in format-string-based attacks).

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•