由於sprintf會導致一些緩衝區溢出,因此我需要將項目中的所有sprintf更改爲snprintf。但我得到了一些麻煩如下:如何確定snprintf dest緩衝區大小
void foo(char *a, uchar *string)
{
sprintf(string, 'format', src_str);
}
的問題是,當目標字符串的函數,如何確定緩衝區大小或字符串的最大長度後,我們改變的snprintf的參數..
由於sprintf會導致一些緩衝區溢出,因此我需要將項目中的所有sprintf更改爲snprintf。但我得到了一些麻煩如下:如何確定snprintf dest緩衝區大小
void foo(char *a, uchar *string)
{
sprintf(string, 'format', src_str);
}
的問題是,當目標字符串的函數,如何確定緩衝區大小或字符串的最大長度後,我們改變的snprintf的參數..
如果您可以選擇自行分配目標緩衝區,則可以使用strlen()
來檢查源字符串的長度,以防其爲null-terminatd併爲其分配足夠大的緩衝區並終止空字符。如果可用,您也可以直接使用asprintf
。 如果您沒有該選項,則必須將目標緩衝區的大小作爲參數傳遞,因爲如果只有指向它的指針,則無法從函數內可靠地確定其大小(除非目標緩衝區始終在一個獨特的可識別的方式)。
調用_scprintf(...)會告訴你該字符串有多大,而不實際使用緩衝區。
然後你分配一個這樣大小的緩衝區,然後調用snprintf。
此解決方案不符合XPG7或C11標準。使用snprintf()函數會。 – 2014-09-04 19:52:53
當調用foo時,如果字符串指向一個數組,看起來-scprintf()將不起作用。'string =&Array [len]; foo((char *)a,string);' – unnugi 2014-09-04 20:34:36
如果您無法使用正確的參數調用snprintf
,只需將sprintf
更改爲snprintf
即可獲得任何優惠。您的foo
函數還需要額外的參數,就像snprintf
需要一個超過sprintf
的額外參數。由於數組在被用作函數的參數時衰減爲指針,因此任何大小的信息都會丟失。
如果您在整個程序中調用foo
幾百次,這可能會讓您感到痛苦,但是如果您想確保避免緩衝區溢出,則需要確保對陣列進行操作的任何函數都完全知曉的大小。
如果使用GCC或鐺,你可以通過改變它的原型放在foo
功能的棄用警告:
void __attribute__((deprecated)) foo(char *a, uchar *string);
然後,您可以創建一個新的功能,例如foo_n
,它有大小的額外參數。當你編譯你的代碼時,GCC會爲每個使用函數foo
發出一個警告,所以你知道用foo_n
替換它們。
1.有可能是__attribute__((deprecated))
部分後去參數列表,但鐺似乎接受它作爲示出了高於它。
您必須將緩衝區大小傳遞給函數。 – Kevin 2014-09-04 18:22:53
調用'int len = snprintf(NULL,0,....)',然後'char buf [len]; snprintf(buf,len,....);'現在至少'buf'具有完整的字符串。至於有多少符合'字符串' - 你是獨立的。 – chux 2014-09-04 19:40:52
除了向函數添加新的大小參數外,還有一個選項是創建一個'struct ustring'來存放指針和緩衝區大小。如果你喜歡,你可以將字符串大小添加到結構體中,這允許你使用更快的函數,比如'memcpy'而不是'strcpy'。 – 2014-09-04 23:04:55