[C] 每天來點字串用法 (2) - strcpy()、strncpy()
結果隔了四天(不要相信 blogger 自帶的時間(?))才更新qwq,前幾天根本忘得一乾二淨XD
進入正文吧,今天要介紹的是:
函式宣告:
1) 第一個參數是目的地 (dest),第二個是來源 (src)
2) 會有緩衝區溢位 (buffer overflow) 的問題
來看看何謂緩衝區溢位:假設有一程式進行了如下宣告:
如果今天我們進行了如下操作:
於是這時 i 的值就會變成 121,我們可以用以下程式來驗證:
為了解決這樣的問題,我們可以改用 strncpy(),他比 strcpy() 多了一個參數:count,用來控制最多複製幾個字元,而它一樣會回傳 dest 指向的字串。這裡也有些地方要注意:
1) 如果 src 字元數(含 '\0')比 count 少,會把剩下未滿 count 的部分通通補上 '\0'
2) 如果 src 字元數(含 '\0')比 count 多,他不會幫你補 '\0',而是要自己補
strncpy() 的使用可參考以下範例:
2) dest 和 src 有重疊的部分*
3) 如果 dest 指到的不是一個字元陣列
4) 如果 src 指向的字串沒有以 '\0' 結尾
2) 如果 dest 或 src 其中一個不是指向一個字串
3) 如果 dest 不夠長(比 count 短)
4) 如果 src 比 count 短而且 src 沒有以 '\0' 結尾
* 其實這個部分在 C99 已受到限制:宣告中新增了 restrict 關鍵字,關於這個關鍵字有興趣的人可以自己查查看
天啊不是我在說,blogger 首頁的文章預覽圖也太醜了吧qq,而且是發佈後才知道ˊˇˋ
希望我可以堅持下去。(已對自己無信心
參考資料:
1) cppreference - strcpy
2) cppreference - strncpy
3) 我休息了4天的腦袋
進入正文吧,今天要介紹的是:
- strcpy()、strncpy():字串複製
函式宣告:
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 <stdio.h>
#include <string.h>
int main(void){
int i = 5;
char s[8] = "Hi 1234";
printf("address of i: %p\naddress of s: %p\n", &i, s); // i: 0028ff1c, s: 0028ff14
strcpy(s, "hello sky");
printf("value of s: %s\nvalue of i: %d\n", s, i); // s: hello sky, : 121
return 0;
}
為了解決這樣的問題,我們可以改用 strncpy(),他比 strcpy() 多了一個參數:count,用來控制最多複製幾個字元,而它一樣會回傳 dest 指向的字串。這裡也有些地方要注意:
1) 如果 src 字元數(含 '\0')比 count 少,會把剩下未滿 count 的部分通通補上 '\0'
2) 如果 src 字元數(含 '\0')比 count 多,他不會幫你補 '\0',而是要自己補
strncpy() 的使用可參考以下範例:
#include <stdio.h>
#include <string.h>
int main(void){
int i = 67; // ASCII 的 'C'
char s[8] = "Hi 1234";
printf("address of i: %p\naddress of s: %p\n", &i, s);
strncpy(s, "hello sky", 8);
printf("(1) value of s: %s\nvalue of i: %d\n", s, i); // s: hello skC, i: 67
s[7] = '\0'; // 自己補 '\0'
printf("(2) value of s: %s\n", s); // s: hello s
return 0;
}
- Undefined Behavior
- strcpy()
2) dest 和 src 有重疊的部分*
3) 如果 dest 指到的不是一個字元陣列
4) 如果 src 指向的字串沒有以 '\0' 結尾
- strncpy()
2) 如果 dest 或 src 其中一個不是指向一個字串
3) 如果 dest 不夠長(比 count 短)
4) 如果 src 比 count 短而且 src 沒有以 '\0' 結尾
* 其實這個部分在 C99 已受到限制:宣告中新增了 restrict 關鍵字,關於這個關鍵字有興趣的人可以自己查查看
天啊不是我在說,blogger 首頁的文章預覽圖也太醜了吧qq,而且是發佈後才知道ˊˇˋ
希望我可以堅持下去。(已對自己無信心
參考資料:
1) cppreference - strcpy
2) cppreference - strncpy
3) 我休息了4天的腦袋
留言
張貼留言