[英]strncpy is not working as expected
#include <iostream>
using namespace std
#include <string.h>
int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5);
c[strlen(c)] = '\0';
cout<<c;
return 0 ;
}
我的輸出是: some random string
。 但我希望它是: some
。 任何人都可以解釋為什么它會這樣嗎?
它工作得很好,請記住, strncpy
不必對字符串進行null終止 。 執行此操作時:
strncpy(c, token, 5);
它將token
的前5個字節復制到c
但不對結果進行空終止 。 此外,此行是無用的:
c[strlen(c)] = '\0';
strlen(c)
查找現有的空終止符,一旦找到一個空終止符,便用另一個無意義的空終止符覆蓋它。
在新代碼中, 很少使用strncpy
。 它的預期用途(固定長度的緩沖區不一定是空終止的)早就被淘汰了。 最好改用諸如strlcpy
類的函數(注意: strlcpy
不是標准的;它僅在類似BSD的系統中可用)。
或者,如果您使用C ++而不是純C進行編碼,則只需使用std::string
並完全避免此類棘手的問題。
我認為您的輸出應該是“一些隨機字符串”,因為您的兩行代碼什么都不做,請參見注釋。
int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5); // Does nothing
c[strlen(c)] = '\0'; // Does nothing
cout<<c;
return 0 ;
}
如果要輸出“ some”,則可以執行以下操作:
strncpy(c, token, 5);
c[5] = '\0';
strncpy()不會自動在目標字符串中添加尾隨“ \\ 0”。 如果源字符串的長度大於len(strncpy的第三個參數),則將len個字符復制到dest中,而不以'\\ 0'結尾。 因此,您必須通過代碼明確給定尾隨“ \\ 0”。
您需要在單詞“ some”之后使null終止,而不是在整個字符串之后使null終止。 strncpy會將“ some”復制到c中,但不一定將null終止您的字符串(有關strncpy,請參見手冊頁)
c[4] = '\0'
正如其他人提到的那樣,與snprintf
到sprintf
不同, strncpy
並不是strcpy
的安全版本。 它僅確保“恰好將N個字符復制到目標位置(如果源字符串短於N,則使用NUL)”。 (手冊頁)
但我認為您已經注意到這一點
c[strlen(c)] = '\0';
這意味着確保c
的空終止。 但這實際上是沒有意義的,因為strlen
使用NUL來確定c
的長度。 因此,這行幾乎不意味着“找到NUL並將NUL寫入該位置”。
strncpy
的重要性是復制字符串的certian部分。 它不是對strcpy
的修復,並且在引入snprintf
函數之前就已存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.