1. m$:表示参数列表中的第m个参数,其中m为int类型常数
eg: printf("The heximal value of %d is 0x%1$02x\n", 15);
打印结果为:
The heximal vaule of 15 is 0x0f
上例中的%1$表明当前转换格式(converion specification)转换的是参数列表中的第一个参数,即15,这样就可以实现在一个printf中重复引用相同的参数,第二个转换格式'%1$02x'中的02x表示当前的转换格式域宽(参看用法2)为2,即至少占用两个字符的宽度,不够的宽度用0填充,02x中的'0'为标志字符(flag character),表示使用0进行填充,默认是用空格(blanks)填充的。
2. %m(conversion specifier):指示转换域宽,其中(conversion specifier)为转换指示字符,如常见的d(表示int),s(表示string),m表示转换后的字符串最小占用的长度,即此次转换后域的宽度,有以下两种情况:
1) m为int类型常数
eg1: printf("The num is %4d.\n", 1);
Result:
The num is 1.
eg2: printf("The num is %4d.\n", 10000);
Result:
The num is 10000.
这个例子表明如果域宽m小于转换后字符串实际占用的宽度,转换后的字符串不会被截断,会占用实际的宽度。
2) m为*或*(num)$,*表示下一个参数的值(即下一个待转换的参数),*(num)$表示第num个参数的值,当然这些参数必须是int类型
eg1: printf("The num is %*d.\n", 4, 1);
Result:
The num is 1.
eg2: printf("The num is %1$*2$d.\n", 1, 4);
Result:
The num is 1.
注意:如果用这种格式指定域宽,最好同时指定当前转换参数的索引,即此例中的%1$,参考用法1,否则会有编译Warning。
例如在mtd-utils中的一个例子,就运用了上述两个规则,以下是代码片段,您可以下载附件中的代码编译运行:
(引自mtd-utils-1.5.0 ubi-utils/mtdinfo.c)
#define PROGRAM_NAME "mtdinfo"
#define VERSION "1.5.0"
printf(
"%1$s version %2$s - a tool to print MTD information.\n"
"\n"
"Usage: %1$s <MTD node file path> [--map | -M] [--ubi-info | -u]\n"
" %1$s --all [--ubi-info | -u]\n"
" %1$s [--help | --version]\n"
"\n"
"Options:\n"
"-u, --ubi-info print what would UBI layout be if it was put\n"
" on this MTD device\n"
"-M, --map print eraseblock map\n"
"-a, --all print information about all MTD devices\n"
" Note: `--all' may give less info per device\n"
" than, e.g., `mtdinfo /dev/mtdX'\n"
"-h, --help print help message\n"
"-V, --version print program version\n"
"\n"
"Examples:\n"
" %1$s /dev/mtd0 print information MTD device /dev/mtd0\n"
" %1$s /dev/mtd0 -u print information MTD device /dev/mtd0\n"
" %4$*3$s and include UBI layout information\n"
" %1$s -a print information about all MTD devices\n",
PROGRAM_NAME, VERSION, (int)strlen(PROGRAM_NAME) + 3, "");
熟练运用这些规则,可以写出比较精炼,紧凑的程序,而且程序也较易读,易于调试。
附件: 点击打开链接
eg: printf("The heximal value of %d is 0x%1$02x\n", 15);
打印结果为:
The heximal vaule of 15 is 0x0f
上例中的%1$表明当前转换格式(converion specification)转换的是参数列表中的第一个参数,即15,这样就可以实现在一个printf中重复引用相同的参数,第二个转换格式'%1$02x'中的02x表示当前的转换格式域宽(参看用法2)为2,即至少占用两个字符的宽度,不够的宽度用0填充,02x中的'0'为标志字符(flag character),表示使用0进行填充,默认是用空格(blanks)填充的。
2. %m(conversion specifier):指示转换域宽,其中(conversion specifier)为转换指示字符,如常见的d(表示int),s(表示string),m表示转换后的字符串最小占用的长度,即此次转换后域的宽度,有以下两种情况:
1) m为int类型常数
eg1: printf("The num is %4d.\n", 1);
Result:
The num is 1.
eg2: printf("The num is %4d.\n", 10000);
Result:
The num is 10000.
这个例子表明如果域宽m小于转换后字符串实际占用的宽度,转换后的字符串不会被截断,会占用实际的宽度。
2) m为*或*(num)$,*表示下一个参数的值(即下一个待转换的参数),*(num)$表示第num个参数的值,当然这些参数必须是int类型
eg1: printf("The num is %*d.\n", 4, 1);
Result:
The num is 1.
eg2: printf("The num is %1$*2$d.\n", 1, 4);
Result:
The num is 1.
注意:如果用这种格式指定域宽,最好同时指定当前转换参数的索引,即此例中的%1$,参考用法1,否则会有编译Warning。
例如在mtd-utils中的一个例子,就运用了上述两个规则,以下是代码片段,您可以下载附件中的代码编译运行:
(引自mtd-utils-1.5.0 ubi-utils/mtdinfo.c)
#define PROGRAM_NAME "mtdinfo"
#define VERSION "1.5.0"
printf(
"%1$s version %2$s - a tool to print MTD information.\n"
"\n"
"Usage: %1$s <MTD node file path> [--map | -M] [--ubi-info | -u]\n"
" %1$s --all [--ubi-info | -u]\n"
" %1$s [--help | --version]\n"
"\n"
"Options:\n"
"-u, --ubi-info print what would UBI layout be if it was put\n"
" on this MTD device\n"
"-M, --map print eraseblock map\n"
"-a, --all print information about all MTD devices\n"
" Note: `--all' may give less info per device\n"
" than, e.g., `mtdinfo /dev/mtdX'\n"
"-h, --help print help message\n"
"-V, --version print program version\n"
"\n"
"Examples:\n"
" %1$s /dev/mtd0 print information MTD device /dev/mtd0\n"
" %1$s /dev/mtd0 -u print information MTD device /dev/mtd0\n"
" %4$*3$s and include UBI layout information\n"
" %1$s -a print information about all MTD devices\n",
PROGRAM_NAME, VERSION, (int)strlen(PROGRAM_NAME) + 3, "");
熟练运用这些规则,可以写出比较精炼,紧凑的程序,而且程序也较易读,易于调试。
附件: 点击打开链接