在下面的代碼例子中,name
可能來自用戶輸入,文件系統或者網絡。程序從字符串構造文件名,爲打開文件做準備
#include <stdio.h>
void func(const char *name) {
char filename[128];
sprintf(filename, "%s.txt", name);
}
因爲sprinf
函數不保證輸入字符串的長度,一個超長的字符串可能會導致一個內存溢出。
格式化字符串%s
可以指定精度,該精度表示格式化字符串最大的長度,例如:%123s
保證名字中最多有123個字符。這樣就保證了filename不會內存溢出。
#include <stdio.h>
void func(const char *name) {
char filename[128];
sprintf(filename, "%.123s.txt", name);
}
當然,最好的方式是用snprinf函數替代sprintf函數
#include <stdio.h>
void func(const char *name) {
char filename[128];
snprintf(filename, sizeof(filename), "%s.txt", name);
}
注意: snprintf中的size選項大小包含字符串末尾的'\0'
,所以可以直接用sizeof來計算大小。
printf中的%123s
不包含字符串結束符'\0'
,所以要比實際小一個字符。
代碼來自:卡耐基梅隆大學軟件研究學院