2011-05-09 136 views
32
#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); 

有没有更好的方法来做到这一点?printf字符串,可变长度项目

+0

您似乎在构建一个格式字符串。但是你应该将'sprintf'返回的字符串赋给'fmt_string','fmt_string'不应该放在参数列表中。 – pavium 2011-05-09 03:41:16

+0

有没有什么特别的原因让你说'letters'不会以null结尾? – 2011-05-09 03:53:47

+1

@AndrewKeeton这是针对一个大型数据集的搜索问题,我无法承受空间容纳空字符。 – 2014-10-11 19:46:17

回答

94

没有必要构造一个特殊的格式字符串。如果您使用.*作为格式标记的精度,则可以使用printf指定使用参数(该值在值之前)的精度。

例如:

printf ("%d %.*s", number, SIZE, letters); 

注意:有宽度之间和精度区分(这是一个最小字段宽度)(其给出的字符的最大数目将被打印)。 %*s指定宽度,%.s指定精度。 (你也可以使用%*.*但随后你需要两个参数,一个是宽一个用于精确度)(Linux下man 3 printf

又见printf的手册页和特别是部分现场宽度和精度:

相反十进制数字串之一可写的“*”或“*米$”(对于某些 十进制整数m)至指定的精度在下一 参数给出,或在第m个参数,它们必须是int类型的。

+0

让他们混淆了...... scanf是没有这个选项的人。 – 2011-05-16 03:56:43

+5

它也适用于2个长度,如''%*。* s“,minlength,maxlength,letters'。 – 2013-09-11 12:39:18

+0

注意:'“* m $”'不是标准C. – chux 2016-03-13 23:58:42

3

一个未知的功能是asprintf。第一个参数是**char。这个函数将malloc作为字符串的空间,所以你不必记帐。记住要完成字符串free

char *fmt_string; 

asprintf(&fmt_string, "%%d %%%ds", SIZE); 
printf(fmt_string, number, letters); 
free(fmt_string); 

是一个使用的例子。

+3

虽然asprintf确实是一个有趣的功能,但重要的是要注意它是一个GNU扩展。另外,我不确定这是如何解决这个问题的。 – Trent 2011-05-09 04:20:29

+1

@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)现在也有。 – 2014-10-14 01:09:12

相关问题