C++ 中 strcpy、strcpy_s、strncpy、strlcpy的異同

來源:互聯網
上載者:User

標籤:

strncpy的用法:它與strcpy的不同之處就在於複製n個字元,而不是把所有字元拷貝(包括結尾‘\0‘)。

函數原型:char * strncpy(char *dst,const char * src, int n)

src的長度小於n時,dst內的未複製空間用‘\0‘填充。否則,複製n個字元到dst,沒有加‘\0‘。這裡就要注意在字串dst結尾處理加‘\0‘的情況了

strcpy ,strncpy ,strlcpy的用法好多人已經知道利用strncpy替代strcpy來防止緩衝區越界。但是如果還要考慮運行效率的話,也許strlcpy是一個更好的方式。

strcpy

我們知道,strcpy 是依據 \0 作為結束判斷的,會自動在緩衝區的string後加\0,如果 to 的空間不夠,則會引起 buffer overflowstrcpy 常規的實現代碼如下(來自 OpenBSD 3.9):

char *strcpy(char *to, const char *from){       char *save = to;       for (; (*to = *from) != ‘\0‘; ++from, ++to);       return(save);}

但通常,我們的 from 都來源於使用者的輸入,很可能是非常大的一個字串,因此 strcpy 不夠安全。

strcyp_s

它和strcpy()函數的功能應該一樣的。strcpy函數,就象gets函數一樣,它沒有方法來保證有效緩衝區尺寸,所以它只能假定緩衝足夠大來容納要拷貝的字串。在程式運行時,這將導致不可預料的行為。用strcpy_s就可以避免這些不可預料的行為。

這個函數用兩個參數、三個參數都可以,只要可以保證緩衝區大小。

三個參數時:

errno_t strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource);

兩個參數時:

errno_t strcpy_s(char (&strDestination)[size], const char *strSource ); // C++ only 

需要注意的是如果需要使用兩個參數的版本,則strDestination所指向的空間必須時靜態分配的,而不能是動態new出出來的堆記憶體。

strncpy

ANSI C 中,strcpy 的安全版本是 strncpy

char *strncpy(char *s1, const char *s2, size_t n);

strncpy 其行為是很詭異的(不符合我們的通常習慣)。標準規定 n 並不是 sizeof(s1),而是要複製的 char 的個數。一個最常見的問題,就是 strncpy 並不幫你保證 \0 結束。

char buf[8];strncpy( buf, "abcdefgh", 8 );

看這個程式,buf 將會被 "abcdefgh" 填滿,但卻沒有 \0 結束符了。
另外,如果 s2 的內容比較少,而 n 又比較大的話,strncpy 將會把之間的空間都用 \0 填充。這又出現了一個效率上的問題,如下:

char buf[80];strncpy( buf, "abcdefgh", 79 );

上面的 strncpy 會填寫 79 個 char,而不僅僅是 "abcdefgh" 本身。

strncpy 的標準用法為:(手工寫上 \0

strncpy(path, src, sizeof(path) - 1);path[sizeof(path) - 1] = ‘\0‘;len = strlen(path);
strlcpy

複製src到大小為size目的緩衝區,最多複製siz-1個,第size個位置會被添加‘\0‘,執行結束後會返回strlen(src)。所以,如果retval >= siz,那麼由於目的緩衝區太小src被截斷了.

size_t strlcpy(char *dst, const char *src, size_t siz);

使用 strlcpy,就不需要我們去手動負責 \0 了,僅需要把 sizeof(dst) 告之 strlcpy 即可:

strlcpy(path, src, sizeof(path));len = strlen(path);if ( len >= sizeof(path) )       printf("src is truncated.");

並且 strlcpy 傳回的是 strlen(str),因此我們也很方便的可以判斷資料是否被截斷,但同時也給程式埋了一個雷,所以,strlcpy 並不屬於 ANSI C,至今也還不是標準。

C++ 中 strcpy、strcpy_s、strncpy、strlcpy的異同

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.