像“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$
适用于整个格式规范,因此第二个参数是将打印其值的参数。