一.strcpy()、strncpy():字串複製
所屬標頭檔:<string.h>
char *strcpy( char *dest, const char *src );
char *strncpy( char *dest, const char *src, size_t count );
strcpy()
將來源字串 (src) 複製到目的地 (dest),並回傳 dest 指向的字串,要注意的有以下兩點:
1) 第一個參數是目的地 (dest),第二個是來源 (src)
2) 會有緩衝區溢位 (buffer overflow) 的問題
來看看何謂緩衝區溢位:假設有一程式進行了如下宣告:
int i = 5;
char s[8] = "Hi 1234";
那麼這些變數的記憶體配置可能如下:
如果今天我們進行了如下操作:
strcpy(s, "hello sky");
那麼記憶體裡的內容就會變成如下:
於是這時 i 的值就會變成 121,我們可以用以下程式來驗證:
#include <iostream>
#include<string.h>
using namespace std;
int main(){
int i = 5;
char s[8] = "Hi 1234";
cout<<"address of i: "<<&i<<"\naddress of s:"<<&s<<endl; // i: 0028ff1c, s: 0028ff14
strcpy(s, "hello, how are you ");
cout<<"value of s: "<<s<<"\nvalue of i:"<<i; // s: hello sky, : 121
}
2.strncpy
為了解決這樣的問題,我們可以改用 strncpy(),
比 strcpy() 多了一個參數:count,用來控制最多複製幾個字元,而它一樣會回傳 dest 指向的字串。
這裡也有些地方要注意:
1) 如果 src 字元數(含 '\0')比 count 少,會把剩下未滿 count 的部分通通補上 '\0'
2) 如果 src 字元數(含 '\0')比 count 多,他不會幫你補 '\0',而是要自己補
strncpy() 的使用
#include <iostream>
#include<string.h>
using namespace std;
int main(){
int i = 67;// ASCII 的 'C'
char s[8] = "Hi 1234";
cout<<"address of i: "<<&i<<"\naddress of s:"<<&s<<endl; // i: 0028ff1c, s: 0028ff14
strncpy(s, "hello,how are you", 8);
// s[7] = '\0'; // 自己補 '\0'
cout<<"value of s: "<<s<<"\nvalue of i:"<<i; // s: hello sky, : 121
}
Undefined Behavior
在使用這兩個函式時,可能會造成 undefined behavior,以下列舉可能的情況:
strcpy()
1) 緩衝區溢位 ※ 其實是 dest 不夠長
2) dest 和 src 有重疊的部分*
3) 如果 dest 指到的不是一個字元陣列
4) 如果 src 指向的字串沒有以 '\0' 結尾
strncpy()
1) dest 和 src 有重疊的部分*
2) 如果 dest 或 src 其中一個不是指向一個字串
3) 如果 dest 不夠長(比 count 短)
4) 如果 src 比 count 短而且 src 沒有以 '\0' 結尾