2011-05-09 106 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

相關問題