UNIX 中 printf 指定参数绑定顺序
UNIX 中的 printf
Single UNIX Specification 中允许 printf
使用 %m$
和 *m$
的形式来绑定第 m 个参数,其中 m 从 1 开始计数。如果使用了这种表达方式,则所有参数都要指定序号,而且不能遗漏参数。这样做的好处是:可以多次使用同一个参数。
请注意,参数是 %m$
和 *m$
这两个结构索取的。这意味着以下两行的含义相同:
printf("%*d", width, num);
printf("%2$*1$d", width, num);
首先 %2$
索要了参数 num
用来表示输出的数字,然后 *m$
索要了参数 width 来表示输出的宽度。这和我们看到的 %*d
的参数顺序有差异:%*d
中就好像输出数字这个参数是 d
索取的一样。相关链接:StackOverflow 的提问。
C99 中没有规定这种指定序号绑定参数的方式。
对比:Java 中的 printf
在 Java 中,printf
由 Formatter
类支持。这种多次使用一个参数的用法可以极大地方便日期的输出。比如:
Date date = new Date();
System.out.printf("%1$tH:%1$tM:%1$tS %1$tp %1$tL %1$tN %1$tz %n", date);
测试打印结果:
00:43:08 上午 280 280000000 +0800
不过,像 UNIX 那样用下标指定打印数和宽度没有成功。后来发现 Java 的格式化器不支持 *
。不只是 *m$
,是 variable width / precision 这一整个功能都不支持!
public class Main {
public static void main(String args[]) {
int width = 4;
int num = 7;
System.out.printf("%2$*1$d", width, num);
}
}
// Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = '2'
Java 的 printf
还有一些其他扩展,比如说可以用 ^
居中。