隨著對(duì)代碼安全性的要求越來(lái)越高,strncpy正式登上了歷史舞臺(tái)。
strncpy在項(xiàng)目中使用較多,一不注意可能會(huì)出錯(cuò),因此記錄一下,方便后續(xù)翻閱查看。
strncpy函數(shù)原型
char * strncpy(char * str2, char * str1, int size);
基本用法
char src[20] = {0};
strncpy(src, "This is test string", sizeof(src)-1);
printf("src[%s]\n", src);
打印結(jié)果為:
src[This is test ]
遇到指針之后
char src[20] = {0};
strncpy(src, "This is test string", sizeof(src)-1);
char* dst = (char*)malloc(20);
strncpy(dst, src, sizeof(dst)-1);
printf("src[%s],len[%d]\ndst[%s],len[%d]\n", src, strlen(src), dst, strlen(dst));
運(yùn)行結(jié)果如下:
src[This is test ],len[19]
dst[Thi],len[3]
我們發(fā)現(xiàn)運(yùn)行結(jié)果出現(xiàn)了異常。原因的sizeof計(jì)算指針變量的大小時(shí),并不是返回指針?biāo)赶虻目臻g的大小,而是指針變量本身的大小,在32位系統(tǒng)中為4字節(jié),因此,目標(biāo)字符串長(zhǎng)度為3,被無(wú)意間截?cái)嗔恕?/p>
為了避免這種情況,我們常使用如下方式調(diào)用strncpy:
char src[20] = {0};
strncpy(src, "This is test string", sizeof(src)-1);
char* dst = (char*)malloc(20);
strncpy(dst, src, strlen(src)+1);
printf("src[%s],len[%d]\ndst[%s],len[%d]\n", src, strlen(src), dst, strlen(dst));
此時(shí),結(jié)果就正常了。
注意,此時(shí)使用的是strlen(src)+1,而不是strlen(dst)-1。
總結(jié)
- 安全拷貝字符串,使用strncpy函數(shù)
- 注意拷貝字符串的長(zhǎng)度計(jì)算,字符數(shù)組可使用sizeof計(jì)算,字符指針需要使用原字符串長(zhǎng)度(strlen(src)+1),+1是因?yàn)楫?dāng)拷貝的長(zhǎng)度size大于待拷貝字符串長(zhǎng)度時(shí),strncpy函數(shù)會(huì)在后面自動(dòng)補(bǔ)上'\0'。我們多拷貝一個(gè)字符,相當(dāng)于讓strncpy函數(shù)幫忙在目標(biāo)字符串結(jié)尾加上'\0'結(jié)束符。
- sizeof計(jì)算指針變量長(zhǎng)度,是int類型在該系統(tǒng)所占內(nèi)存的大小