字串連接:strcat()、strncat()
比照strcpy()與strncpy(),做個筆記吧。順帶一提,一副貓樣的cat是concatenate的縮寫。
strncat()
函式宣告
顯示「.」代表未改變,保持原始值。
顯示「_」代表字串結尾字元「\0」。
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()
函式宣告
顯示「.」代表未改變,保持原始值。
顯示「_」代表字串結尾字元「\0」。
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(),當
紅底格子為溢位的位址。
同樣的,使用strncat(),當
紅底格子為溢位的位址。可設定
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以策安全。
留言
張貼留言