printf字符串,可变长度项

Wil*_*ken 39 c format printf

#define SIZE 9
int number=5;
char letters[SIZE]; /* this wont be null-terminated */
... 

char fmt_string[20];
sprintf(fmt_string, "%%d %%%ds", SIZE);
/* fmt_string = "%d %9d"... or it should be */

printf(fmt_string, number, letters);
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

Tre*_*ent 107

无需构造特殊格式字符串. printf如果.*在格式标记中使用a 作为精度,则允许您使用参数(在值之前)指定精度.

例如:

printf ("%d %.*s", number, SIZE, letters);
Run Code Online (Sandbox Code Playgroud)

注意:宽度(最小字段宽度)和精度(给出要打印的最大字符数)之间存在区别. %*s指定宽度,%.s指定精度.(你也可以使用%*.*但是你需要两个参数,一个用于宽度一个用于精度)

另请参见printf手册页(man 3 printf在Linux下),特别是有关字段宽度和精度的部分:

可以写"*"或"*m $"(对于某些十进​​制整数m)来指定精度在下一个参数或第m个参数中给出,而不是十进制数字串,必须是int类型

  • 它也适用于2个长度,如"%*.*s",minlength,maxlength,letters`. (6认同)
  • 有没有办法让"%.*s"格式接受`size_t`而不是`int`? (2认同)

No *_*lar 5

某种未知的功能是asprintf。第一个参数是**char。此函数将为malloc字符串留出空间,因此您不必进行簿记。完成后记住free字符串。

char *fmt_string;

asprintf(&fmt_string, "%%d %%%ds", SIZE);
printf(fmt_string, number, letters);
free(fmt_string);
Run Code Online (Sandbox Code Playgroud)

是一个使用示例。

  • 尽管asprintf确实是一个有趣的功能,但必须注意它是一个gnu扩展。另外,我不确定这如何解决这个问题。 (3认同)
  • @Trent,它确实是作为 GNU 扩展开始的,但同时 [OpenBSD](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/asprintf.3) , [FreeBSD](http://www.freebsd.org/cgi/man.cgi?query=asprintf) 和 [NetBSD](http://netbsd.gw.com/cgi-bin/man-cgi?asprintf)已经实施了。甚至 [Mac OS X](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/asprintf.3.html) 现在都有了。 (2认同)