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

Je *_*Rog 15 c format printf

通过man我找到

               printf("%*d", width, num);
Run Code Online (Sandbox Code Playgroud)

               printf("%2$*1$d", width, num);
Run Code Online (Sandbox Code Playgroud)

是等价的.

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

               printf("%*d", num, width);
Run Code Online (Sandbox Code Playgroud)

但通过测试似乎man是正确的; 为什么?

Jon*_*ler 26

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

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

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

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

%n$识别,其值是要被打印的参数-参数2中的例子.

*n$标识其值被视为格式宽度参数-在您的示例参数1.

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


你在评论中争论:

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

正如已经指出的,该标准明确地附着的n$部件作为后缀改性剂%*,而不是作为格式转换指定的前缀改性剂(d在本例中)和*.您的推定设计可能会起作用,但不是选择的设计.


R..*_*R.. 5

在你的第二个例子中:

printf("%2$*1$d", width, num);
Run Code Online (Sandbox Code Playgroud)

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