像“1 $”这样的位置参数如何与printf()一起使用?

通过man我发现

  printf("%*d", width, num); 

  printf("%2$*1$d", width, num); 

是等价的。

但IMO的第二种风格应该是:

  printf("%*d", num, width); 

然而通过测试似乎man是对的; 为什么?

printf()的POSIX规范的相关部分定义了这种行为:

转换可以应用于参数列表中格式之后的第n个参数,而不是下一个未使用的参数。 在这种情况下,转换说明符字符%(见下文)被序列“%n $”替换,其中n是[1,{NL_ARGMAX}]范围内的十进制整数,给出参数在参数中的位置名单。 此function提供了格式字符串的定义,该格式字符串以适合特定语言的顺序选择参数(请参阅示例部分)。

格式可以包含编号的参数转换规范(即“%n $”和“* m $”),或无编号的参数转换规范(即%和*),但不能同时包含两者。 唯一的例外是%%可以与“%n $”表单混合使用。 在格式字符串中混合编号和未编号参数规范的结果是未定义的。 当使用编号的参数规范时,指定第N个参数要求在格式字符串中指定从第一个到第( N-1 )个的所有前导参数。

在包含转换规范的“%n $”forms的格式字符串中,参数列表中的编号参数可以根据需要多次从格式字符串中引用。

%n$标识要打印其值的参数 – 示例中的参数2。

*n$标识参数,其值将被视为格式宽度 – 示例中的参数1。

因此,编写手册的人遵循标准。


你在评论中争论:

2$*应匹配第二个参数,而1$d应匹配第一个参数,但事实certificate,在printf("%2$*1$d", width, num);的情况下,它不是真的printf("%2$*1$d", width, num);

如前所述,该标准明确地将n$部分作为%*后缀修饰符附加,而不是作为格式转换说明符(本例中为d )和*前缀修饰符。 你的推定设计可能会起作用,但不是选择的设计。

在你的第二个例子中:

 printf("%2$*1$d", width, num); 

第一个数字2附加到格式说明符,第二个数字1附加到* 。 如果您阅读printf的文档,这很清楚。 没有什么不寻常的事情发生。

字段宽度或精度或两者可以用星号’*’或星号后跟一个或多个十进制数字和一个’$’而不是数字字符串表示。

所以1$适用于星号,因此第一个参数是宽度。 2$适用于整个格式规范,因此第二个参数是将打印其值的参数。