strcpy與strncpy的區別

咱們先來看看strcpy, 下面的程序沒有問題:ios

#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = {0};
    char *p = "abc";
    strcpy(str, p);
    cout << str << endl;
 
    return 0;
}
小程序

      可是,我運行下面程序的時候,就有問題了:
#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = {0};
    char *p = "abcdefg";
    strcpy(str, p);
    cout << str << endl;
 
    return 0;
}
     結果以下:
安全


       也許你要說, 這是程序猿不當心, str的空間過小, p指向的串太大,程序猿當心注意一下就行了。真的是這樣嗎?馬虎的程序猿還少嗎?反正,我有時也是馬虎程序猿之一。誰也不敢保證本身在用strcpy的時候,str的空間足夠大。 你想,系統那麼複雜, p指向的串,有時你根本沒法預料,對不對? 因此,要避免這類程序崩潰,不能僅僅依賴於程序猿的細心和認真,儘管咱們能夠儘量細心。函數

      那怎麼辦?咱們看看更安全的strncpy函數吧,原型:char *strncpy(char *dest, char *src, size_t num);spa

上述有問題的程序應該改成:.net


#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = {0};
    char *p = "abcdefg";
    strncpy(str, p, sizeof(str) - 1);
    cout << str << endl;
 
    return 0;
}
      或許,你要說, 上面這樣拷貝後, str中獲得的不是想要的"abcdefg"啊!對,但這樣至少不會致使系統崩潰。最後的問題是:系統不崩潰,但串不對,這樣就相對好定位了。
blog


另外看一下下面這個小程序:內存


#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = {0};
    char *p = "a\0bcdefg";
    strncpy(str, p, sizeof(str) - 1);
    cout << str << endl;
 
    return 0;
}
     結果爲a
字符串


絕對絕對要注意的是: strncpy並無拷貝串後的\0字符,而strcpy卻拷貝了。這充分說明,strncpy是爲拷貝字符而生的,而strcpy是拷貝字符串而生的。但二者都不能越界拷貝。只要正確使用strncpy, 那就比strcpy安全。原型

看看這個程序:


#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = "xyz";
    str[3] = 'w'; //故意將最後的\0換成w
    
    char *p = "abc";
    strcpy(str, p); //把p指向的串拷貝到str中去(恰好能夠容納)
    cout << str << endl;
 
    return 0;
}
      結果爲:abc
再看:

#include <iostream>
using namespace std;
 
int main()
{
    char str[4] = "xyz";
    str[3] = 'w'; //故意將最後的'\0'換成'w'
    
    char *p = "abc";
    strncpy(str, p, sizeof(str) - 1); //只拷貝了3個字符,沒有拷貝'\0'
    cout << str << endl;
 
    return 0;
}
     結果爲:abcw? 異常的結果,固然,在你的機器上極可能是其餘的異常結果。從這個例子能夠看出, 定義str的時候,若是不進行初始化(char str[4] = {0};),那是很是很是危險的!


總結一下:

1. 好的程序猿用strncpy, 先定義並初始化char str[MAX + 1] = {0};, 若是在程序中間須要再往str中拷貝串,必定要用memset清零。 拷貝範式爲:strncpy(str, p, sizeof(str) - 1); , 流氓程序猿用strcpy, 固然我常常在寫博客時這麼幹.

2. strncpy拷貝的是字符,不拷貝串,因此最後一個\0沒有拷貝,因此,拷貝的時候須要對串進行清零處理,必定要養成好習慣。

3. strncpy拷貝時,可能會致使截斷,但程序不會崩潰。

4. 根據上面strncpy的原型,其實strncpy也並不必定拷貝num個字符,有特殊狀況,好比:


#include <iostream> using namespace std;   int main() {     char str[4] = {'w', 'x', 'y', 'z'};     char *p = "a\0bcdefg";     strncpy(str, p, sizeof(str) - 1);       cout << int(str[0]) << endl; // 'a'     cout << int(str[1]) << endl; // '\0'     cout << int(str[2]) << endl; // '\0'   //確實要注意這個值, 不是'b'       cout << int(str[3]) << endl; // 'z'       return 0; }

相關文章
相關標籤/搜索