字串連接:strcat()、strncat()

  比照strcpy()與strncpy(),做個筆記吧。順帶一提,一副貓樣的cat是concatenate的縮寫。

strncat()

函式宣告 char *strncat(char *dest, const char *src, size_t n); 測試範例 #include <stdio.h> #include <string.h> void main() { char src1[] = "abcd"; char src2[] = "123"; char arr[10]; int i, n; for (n = 0; n < sizeof(arr) - strlen(src1); n++) { memset(arr, '.', sizeof(arr)); strncpy(arr, src1, sizeof(src1)); printf("N = %d: ", n); strncat(arr, src2, n); for (i = 0; i < sizeof(arr); i++) { if (arr[i] == '\0') printf("%c ", '_'); else printf("%c ", arr[i]); } printf("\n"); } } 輸出如下:
顯示「.」代表未改變,保持原始值。
顯示「_」代表字串結尾字元「\0」。
N = 0: a b c d _ . . . . . N = 1: a b c d 1 _ . . . . N = 2: a b c d 1 2 _ . . . N = 3: a b c d 1 2 3 _ . . N = 4: a b c d 1 2 3 _ . . N = 5: a b c d 1 2 3 _ . .   結果可以看到,N代表截取src2[]的N個字元,從arr[]字串結尾字元'\0'的位址作起始點,覆寫原有的字串結尾字元,連接src2[]的N個字元後,再補上一個新的字串結尾字元,若N超出strlen(src2),超出的位址之值,除了第一個作為新的字串結尾字元,往後的會原封不動,不像字串複製函式strncpy(),會將超出的位置會自動填'\0'補齊。若想src2[]全部複製,可以選擇N = strlen(src)即可,N再增大,結果依然不變,這種設計比strncpy()還安全。

strcat()

函式宣告 char *strcat(char *dest, const char *src); 測試範例 #include <stdio.h> #include <string.h> void main() { char src1[] = "abcd"; char src2[] = "123"; char arr[10]; int i, n; memset(arr, '.', sizeof(arr)); strncpy(arr, src1, sizeof(src1)); strcat(arr, src2); for (i = 0; i < sizeof(arr); i++) { if (arr[i] == '\0') printf("%c ", '_'); else printf("%c ", arr[i]); } printf("\n"); } 輸出如下:
顯示「.」代表未改變,保持原始值。
顯示「_」代表字串結尾字元「\0」。
a b c d 1 2 3 _ . .   strcat()的效果,與strncpy()第三個參數n設為strlen(src)或以上時等效。

溢位

  arr[]的長度不足,就會溢位,造成程式不安全。使用strcat(),當strlen(src1) + strlen(src2) + 1 > sizeof(arr),超出陣列arr的範圍並不會中斷連接,例如: char src1[] = "abcd"; char src2[] = "123456"; char arr[10]; strcpy(arr, src1); strcat(arr, src2); 結果為
src1[] 'a' 'b' 'c' 'd' '\0'
strcpy(arr, src1) 'a' 'b' 'c' 'd' '\0'
src2[] '1' '2' '3' '4' '5' '6' '\0'
strcat(arr, src2) 'a' 'b' 'c' 'd' '1' '2' '3' '4' '5' '6' '\0'
紅底格子為溢位的位址。
  同樣的,使用strncat(),當strlen(src1) + strlen(src2) + 1 > sizeof(arr)且n ≥ strlen(src2),超出陣列arr的範圍亦不會中斷連接,例如: char src1[] = "abcd"; char src2[] = "123456"; char arr[10]; strncpy(arr, src1, sizeof(arr)); strncat(arr, src2, strlen(src2)); 結果為
src1[] 'a' 'b' 'c' 'd' '\0'
strncpy(arr, src1, sizeof(arr)) 'a' 'b' 'c' 'd' '\0' '\0' '\0' '\0' '\0' '\0'
src2[] '1' '2' '3' '4' '5' '6' '\0'
strncat(arr, src2, strlen(src2)) 'a' 'b' 'c' 'd' '1' '2' '3' '4' '5' '6' '\0'
紅底格子為溢位的位址。可設定n = sizeof(arr) - strlen(arr) - 1以策安全。

留言

這個網誌中的熱門文章

私有IP

echo "text" > file 發生 Permission denied

Git指令彙整