By man
I find
printf("%*d", width, num);
and
printf("%2$*1$d", width, num);
are equivalent.
But IMO the second style should be the same as:
printf("%*d", num, width);
However via testing it seems man
is right; why?
Below are several examples of printing information from variables using fprintf. Notice the use of %s to print a string, and %d to print an integer, and %f to print a number with a decimal (a floating point number).
The %a formatting specifier is new in C99. It prints the floating-point number in hexadecimal form. This is not something you would use to present numbers to users, but it's very handy for under-the-hood/technical use cases. As an example, this code: printf("pi=%a\n", 3.14); prints: pi=0x1.91eb86p+1.
The printf function (the name comes from “print formatted”) prints a string on the screen using a “format string” that includes the instructions to mix several strings and produce the final string to be printed on the screen.
To format a simple string, we'll use the %s combination.printf("%2.2s", "Hi there!"); The first x number in %x. ys syntax is the padding. y is the number of chars.
The relevant part of the POSIX specification of printf()
defines this behaviour:
Conversions can be applied to the nth argument after the format in the argument list, rather than to the next unused argument. In this case, the conversion specifier character % (see below) is replaced by the sequence "%n$", where n is a decimal integer in the range [1,{NL_ARGMAX}], giving the position of the argument in the argument list. This feature provides for the definition of format strings that select arguments in an order appropriate to specific languages (see the EXAMPLES section).
The format can contain either numbered argument conversion specifications (that is, "%n$" and "*m$"), or unnumbered argument conversion specifications (that is, % and * ), but not both. The only exception to this is that %% can be mixed with the "%n$" form. The results of mixing numbered and unnumbered argument specifications in a format string are undefined. When numbered argument specifications are used, specifying the Nth argument requires that all the leading arguments, from the first to the (N-1)th, are specified in the format string.
In format strings containing the "%n$" form of conversion specification, numbered arguments in the argument list can be referenced from the format string as many times as required.
The %n$
identifies the argument whose value is to be printed - argument 2 in your example.
The *n$
identifies the argument whose value is to be treated as the format width - argument 1 in your example.
So, those writing the manual followed the standard.
You argue in a comment:
2$*
should match the 2nd parameter while1$d
should match the first one, but it turns out that it's not true in the case ofprintf("%2$*1$d", width, num);
.
As noted already, the standard clearly attaches the n$
parts as postfix modifiers of %
and *
, rather than as prefix modifiers of the format conversion specifier (d
in this example) and *
. Your putative design could, probably, be made to work, but was not the design chosen.
In your second example:
printf("%2$*1$d", width, num);
The first number, 2, is attached to the format specifier, and the second number, 1, is attached to the *
. If you read the documentation for printf
, this is clear. Nothing unusual is happening.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With