我應該使用什麼,當我想複製src_str
到dst_arr
爲什麼?strincpy或strlcpy在我的情況下
char dst_arr[10];
char *src_str = "hello";
PS:我的頭正在讀的東西很多關於如何好或壞是strncpy
和strlcpy
後紡比我的計算機的磁盤速度更快。
注意:我知道strlcpy
不是隨處可用。這不是關心的問題。
我應該使用什麼,當我想複製src_str
到dst_arr
爲什麼?strincpy或strlcpy在我的情況下
char dst_arr[10];
char *src_str = "hello";
PS:我的頭正在讀的東西很多關於如何好或壞是strncpy
和strlcpy
後紡比我的計算機的磁盤速度更快。
注意:我知道strlcpy
不是隨處可用。這不是關心的問題。
strncpy
是從未正確的答案時,你的目標字符串零終止。 strncpy
是一個函數,旨在與非終止的固定寬度字符串一起使用。更確切地說,它的目的是將零終止的字符串轉換爲非終止的固定寬度的字符串(通過複製)。換句話說,strncpy
在這裏沒有意義。
您在這裏的真正選擇是在strlcpy
和普通strcpy
之間。
當您想要執行「安全」(即可能截短)複製到dst_arr
時,要使用的正確功能是strlcpy
。
dst_ptr
...沒有「複製到dst_ptr
」這樣的東西。您可以複製到dst_ptr
指向的內存,但首先您必須確保它指向某處並分配該內存。有很多不同的方法來做到這一點。
例如,您可以使dst_ptr
指向dst_arr
,在這種情況下,答案與前一個案例中的相同 - strlcpy
。
或者您可以使用malloc
分配內存。如果分配的內存量足夠保證字符串(即至少分配了strlen(src_str) + 1
字節),則可以使用普通的strcpy
甚至memcpy
複製字符串。在這種情況下,沒有必要也沒有理由使用strlcpy
,雖然有些人可能更喜歡使用它,因爲它以某種方式給予他們額外安全的感覺。
如果您有意分配較少的內存(即您希望您的字符串被截斷),那麼strlcpy
將成爲使用的正確函數。
strlcpy()比strncpy()更安全,所以你不妨使用它。
沒有它的系統通常會有一個s_strncpy()來做同樣的事情。
注意你不能複製任何東西到dst_ptr直到它指向的東西
它有點安全,但也不安全。例如。 strlcpy截斷源字符串以適應目標,這是一種安全風險。 – rurban
我不知道strlcpy。我剛剛發現here說:
的strlcpy和strlcat函數複製並分別連接字符串 。它們被設計爲更安全,更一致,並且對於strncpy(3)和strncat(3)來說,更少的容易出錯的替換。
因此stripepy接縫更安全。
編輯:有完整的討論可用here。
EDIT2:
我意識到,我寫上面不回答你的問題的「你的情況」部分。如果你明白 strncpy的侷限性,我猜你可以使用它並在其周圍編寫好的代碼以避免其陷阱;但是如果你不確定你對限制的理解,請使用strlcpy。
我對strncpy和strlcpy的侷限性的理解是,你可以用strncpy(緩衝區溢出)做一些非常糟糕的事情,而用strlcpy可以做的最糟糕的事情是在這個過程中釋放一個字符。
首先,你的dst_ptr沒有分配空間,你沒有設置它指向其他空間,所以指定任何東西都可能導致分段錯誤。
strncpy()函數應該完全正常工作 - 只是做:
strncpy(dst_arr, src_str, sizeof(dst_arr));
,你知道你不會溢出dst_arr。如果使用更大的src_str,則可能必須將自己的空終止符放在dst_arr的末尾,但在這種情況下,您的源是<您的dest,因此無論如何都會填充空值。
這在任何地方都行得通,而且它的安全,所以我不會看別的東西,除非它的智力好奇。
另外請注意,這將是很好用的10非幻數,讓你知道的是,大小strncpy()函數:)
'strncpy'幾乎從不是正確的事情,因爲它零填充但不零終止。 OP希望'strlcpy',它的零終止和不填零。另外,在「這種情況下」討論是錯誤的,因爲當然只是一個例證的問題......真正的代碼不會將像「hello」這樣的固定字符串複製到一個固定大小的緩衝區, 。 –
你不應該使用strncpy()函數,而不是是strlcpy本的尺寸相匹配。更好的使用
*dst_arr=0; strncat(dst_arr,src_arr,(sizeof dst_arr)-1);
或沒有初始化
sprintf(dst_arr,"%.*s",(sizeof dst_arr)-1,src_arr);
dst_arr這裏必須是一個數組不是指針。
'strlcpy'可以用於OP的需要。 –
您應該始終使用標準功能,在本例中爲C11 strcpy_s()
功能。不是strncpy()
,因爲這是不安全的,不保證零終止。而不是僅限於OpenBSD的strlcpy()
,因爲它也是不安全的,而OpenBSD總是提出它自己的發明,而這些發明通常不會成爲任何標準。
參見 http://en.cppreference.com/w/c/string/byte/strcpy
功能strcpy_s類似於BSD功能是strlcpy,不同之處在於 是strlcpy截斷源字符串以適應目的地(這是一個安全風險)
如果您的C庫沒有strcpy_s
,請使用safec庫。 https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html
謝謝。當你說「當你使用零終止的字符串工作時,strncpy從來不是正確的答案」,你的意思是源字符串或dest? – hari
@hari:目標字符串。 'strncpy'是*轉換*函數,它將零終止的源字符串轉換爲非終止的固定寬度目標字符串。 – AnT
所以,如果我的目標字符串是'char dst_arr [10];'這不是空終止的。那我應該用'strlcpy'正確嗎? – hari