2011-03-17 32 views
2

是否有一個函數可以用來預測sprintf()需要的空間? IOW,我可以調用函數size_t predict_space(「%s \ n」,some_string),它將返回將由sprintf(「%s \ n」,some_string)產生的C字符串的長度?預測sprintf()'ed行的len?

+0

爲什麼不在'some_string'上使用'strlen'並用它來計算需要多少空間? – MAK 2011-03-17 11:44:14

+2

@MAK假設OP想要一個通用的解決方案,可以使用不同的格式說明符和多個參數。 – 2011-03-17 11:47:07

+2

根據答案,'snprintf'可能是要走的路。在沒有這個函數的系統中,我們使用了'FILE * fh = fopen(「/ dev/null」,「w」)'然後'x = fprintf(fh,fmtstr,blah,blah,blah);'長度。 – paxdiablo 2011-03-17 11:51:34

回答

9

C99snprintf(注:Windows和SUSv2,不提供的snprintf(或_snprintf的實現)符合標準)

 
     7.19.6.5 The snprintf function 

     Synopsis 

     [#1] 

       #include <stdio.h> 
       int snprintf(char * restrict s, size_t n, 
         const char * restrict format, ...); 

     Description 

     [#2] The snprintf function is equivalent to fprintf, except 
     that the output is written into an array (specified by 
     argument s) rather than to a stream. If n is zero, nothing 
     is written, and s may be a null pointer. Otherwise, output 
     characters beyond the n-1st are discarded rather than being 
     written to the array, and a null character is written at the 
     end of the characters actually written into the array. If 
     copying takes place between objects that overlap, the 
     behavior is undefined. 

     Returns 

     [#3] The snprintf function returns the number of characters 
     that would have been written had n been sufficiently large, 
     not counting the terminating null character, or a negative 
     value if an encoding error occurred. Thus, the null- 
     terminated output has been completely written if and only if 
     the returned value is nonnegative and less than n. 

例如:

len = snprintf(NULL, 0, "%s\n", some_string); 
if (len > 0) { 
    newstring = malloc(len + 1); 
    if (newstring) { 
     snprintf(newstring, len + 1, "%s\n", some_string); 
    } 
} 
+0

可能不是可移植的:關於snprintf的返回值,SUSv2和C99 stan- dard相互矛盾:當snprintf被調用時size = 0,則 SUSv2規定一個未指定的返回值小於1,而C99 允許str在這種情況下爲NULL,並給出返回值(總是爲 ),作爲輸出字符串足夠大時應寫入的字符數 。 – 2011-03-17 11:48:15

+0

@Benoit,你可以使用像'char x; int len = snprintf(&x,1,fmtstr,blah,blah,blah);'在這種情況下。 – paxdiablo 2011-03-17 12:14:39

6

使用可以使用大小爲0的snprintf()來準確找出需要多少個字節。價格是字符串有效格式化兩次。

+0

保重。手冊頁摘錄:snprintf()函數返回格式化爲 的字符數,也就是說,如果足夠大,將會將 寫入緩衝區的字符數。如果在對snprintf()的調用中,n的值爲 ,則返回小於1的未指定的 值。 – 2011-03-17 11:43:01

+2

@Benoit:這不是標準描述的行爲。 – pmg 2011-03-17 11:47:18

+1

關於snprintf的返回值,SUSv2和C99 stan- dard相互矛盾:當snprintf被調用時size = 0,則 SUSv2規定一個未指定的返回值小於1,而C99 允許str爲NULL這種情況下,並且返回值(總是爲 )作爲在 情況下輸出字符串已足夠大的字符數。 – 2011-03-17 11:48:54

2

您可以使用snprintf,如

sz = snprintf (NULL, 0, fmt, arg0, arg1, ...); 

但請參閱Autoconf的portability notes on snprintf

+0

警告:關於snprintf的返回值,SUSv2和C99 stan- dard相互矛盾:當調用snprintf時size = 0,則 SUSv2規定一個未指定的返回值小於1,而C99 允許str爲在這種情況下爲NULL,並給出返回值(總是爲 ),作爲輸出字符串足夠大的情況下寫入的字符數 。 – 2011-03-17 11:47:39

2

在大多數情況下,您可以通過添加要連接的字符串的長度並根據您使用的格式獲取數值的最大長度來計算它。