簡體   English   中英

strncpy文檔問題

[英]strncpy documentation question

關於strncpyhttpstrncpy ,它提到了以下內容:

沒有空字符隱式附加到目標的末尾,因此如果源中的C字符串的長度小於num,則目標將僅以空值終止。

這句話是什么意思?

這意味着,例如,如果源字符串是20個字符加上空終止符並且strncpy指定少於21個字符,則目標字符串將不會附加空值。

這是因為它的工作方式: strncpy保證它將准確寫入N個字節,其中N是傳入的長度值。

如果源字符串的長度(無空字節)小於該字符串,則它將使用空值填充目標區域。 如果它等於或大於,則不會將null添加到目標。

這意味着它在技術上可能不是你得到的C字符串。 這可以通過以下代碼解決:

char d[11];          // Have enough room for string and null.
strncpy (d, s, 10);  // Copy up to 10 bytes of string, null the rest.
d[10] = '\0';        // Then append null manually in case s was too long.

您分配11個字節(數組索引0..10),復制到10(索引0..9)然后將第11個(索引10)設置為null。

這是一個圖表,顯示了使用strncpy (d, s, 10)將各種大小的字符串寫入10個字符區域的三種可能性. 表示空字節:

s              d
-------------  ----------
Hello.         Hello.....
Hello Fred.    Hello Fred
Hello George.  Hello Geor

請注意,在第二種和第三種情況下,不會寫入空字節,因此,如果將d視為字符串,則可能會對結果感到失望。

字符串"foo"有3個字符+ 1個空終止符(它存儲為"foo\\0" ),總長度為4.如果你用n=3 (或更少)調用strncpy ,它將不會附加一個null-終止符到目標字符串的末尾,但只復制"foo" 由於缺少表示字符串結尾的空終止符,因此嘗試打印結果字符串將導致未定義的行為。

您必須非常小心這一點,並且要么傳遞大於最大源的n ,要么自己添加null-terminator。

這意味着它復制源字符串的終止空值,但如果源字符串不適合目標,則不會添加終止空值。

在作為char數組存儲的C字符串中,它們以空值終止,這意味着它們在末尾附加了一個額外的0 ,這標志着字符串的結尾,以后可以用來計算字符串的長度。 所以字符串"hello"在內存中看起來像這樣:

char hello[] = {'h', 'e', 'l', 'l', 'o', 0};

通常,復制字符串時,也應復制null字符。 所以字符串緩沖區所需的內存是它的長度+ 1(例如(strlen(hello) + 1) * sizeof(char) )。

函數strncpy允許您只復制盡可能多的字符以適合提供的緩沖區。 如果您提供的緩沖區不足以容納額外的null ,則不會添加它。 或者,如果字符串被剪切,它將不會以空值終止。

char hello[] = "hello"; // 5 characters, 6 bytes long
char hel[3];
strncpy(hel, hello, 3); // hel is {'h', 'e', 'l'}

調用strncpy后應該總是小心,因為結果可能不是有效的C字符串。 如果字符串不是以null結尾,則無法知道其長度,並且大多數字符串操作函數將失敗或將執行意外操作。

這意味着只有num個字節將從源緩沖區復制到目標緩沖區; 因此,如果源字符串長度大於或等於num ,則不會復制終止NULL字節,並且結果將不具有NULL終止字節,這是危險的。

建議使用strlcpy代替。

strncpy()的語義,即使在上面的C ++參考中被精確解釋,也被廣泛誤解。 此函數的行為是違反直覺且容易出錯的。

為了避免在使用它或進一步開發過程中出現問題,當維護者誤讀代碼並添加更多的漏洞時,有一個簡單的解決方案: 永遠不要使用這個功能

您可以在Bruce Dawson的這篇文章中閱讀有關此內容的更多詳細信息。

回答你的問題:如果源字符串長於作為第三個參數傳遞的大小(通常對應於目標緩沖區的大小),則該函數會將大小字符復制到目標,並且這些字符之間不會出現空字節。 調用strlen(destination); 然后將調用未定義的行為,因為它將嘗試讀取超出數組末尾的內容,直到找到空終止符。 這種特定的行為使得strncpy容易出錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM