我需要你的建議。我使用這種方式復制字串,知道最大大小不會超過,但其中一些字串不以空終止符結尾。這只是一個片段。
void my_strcpy(char* dest, const char* src, const size_t max_size)
{
snprintf(dest, max_size, "%.*s", max_size - 1, src);
}
有沒有更安全的方法?strlcpy
? (我沒有在這里處理錯誤。)
uj5u.com熱心網友回復:
OP 的使用看起來不錯 - 可能在大小限制和精度方面有點迂腐。
"%.*s"
允許指向沒有空字符的字符陣列的指標。復制將限制為精度或空字符,以先到者為準。
結果dest[]
不應該不是以有效引數結尾的空字符。
我會添加一些測驗:
// return error code
int my_strcpy(char* dest, const char* src, size_t max_size) {
assert(dest && src && max_size && max_size < INT_MAX); // Validate arguments.
// v-- use int here --v
int len = snprintf(dest, max_size, "%.*s", (int) (max_size - 1), src);
return (len < 0 || (unsigned) len >= max_size);
}
我懷疑sprintf(dest, "%.*s", max_size - 1, src);
也足夠了,期望它缺乏對過長src
.
當然可以使用類似的東西
void my_strcpy(char* restrict dest, const char* restrict src, size_t size) {
if (dest && src && size) {
while (--size > 0 && *src) {
*dest = *src ;
}
*dest = 0;
}
}
restrict
這里暗示src/dest
不重疊。
uj5u.com熱心網友回復:
由于多種原因,您的方法并不完全安全:
snprintf
%.*s
說明符的精度引數必須強制轉換為int
. 如果size_t
目標系統上的大小不同,則行為未定義。您應該使用演員表(int)(max_size - 1)
。max_size > INT_MAX
即使有演員表,你的方法也會失敗。- 如果
max_size == 0
,snprintf()
可能仍會從 讀取位元組src
,這可能會導致未定義的行為,尤其是在源字串不是空終止的情況下。 - 如果源字串未根據當前選擇的區域設定正確編碼,則
snprintf
可能會停止復制并回傳 -1,使目標沒有空終止符。
目前尚不清楚您要實作的目標:
我使用這種方式復制字串,知道最大大小不會超過,但其中一些字串不以空終止符結尾
是max_size
復制的最大位元組數strncat
還是目標陣列的長度,包括空終止符的空間snprintf
?
哪些字串沒有空終止符?源字串或目標陣列的結果內容?
按照編碼,引數max_size
是目標陣列的長度,包括空終止符。
為了避免上述問題,這里有一些獨立的替代方案:
一個非常容易使用的截斷版本
char array[SIZE];
my_strcpy_trunc(array, sizeof array, source);
// copy source string to an array of length size
// truncate contents to fit in the destination array
// return 0 if successful and no truncation occurred
// return 1 if truncation occurred
// return 2 if src is NULL, destination set to an empty string
// return -1 if arguments are invalid, no copy occurred
int my_strcpy_trunc(char *dest, size_t size, const char *src) {
if (dest && size) {
if (src) {
for (;;) {
if ((*dest = *src ) == '\0')
return 0; // success
if (--size == 0) {
dest[-1] = '\0';
return 1; // truncation occurred
}
}
}
*dest = '\0';
return 2; // src is null pointer
} else {
return -1; // invalid dest
}
}
類似于strncat
您假設目的地至少有n 1
可用位元組的限制版本,恕我直言,這是一種不太安全的方法:
// copy source string up to a maximum of n bytes and set the null terminator to an array of length size
// return 0 if successful
// return 1 if successful and src length larger than n
// return 2 if src is NULL, destination set to an empty string
// return -1 if arguments are invalid, no copy occurred
int my_strcpy_limit(char *dest, const char *src, size_t n) {
if (dest) {
if (src) {
while (n --> 0) {
if ((*dest = *src ) == '\0')
return 0; // success
}
*dest = '\0';
return *src ? 1 : 0;
}
*dest = '\0';
return 2; // src is null pointer
} else {
return -1; // invalid dest
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/383182.html
上一篇:在C中寫入檔案會覆寫變數