天天看點

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

目錄:

  • strcpy()
    • 舉例:
  • memcpy()
    • 舉例:
  • strncpy()
    • 舉例:
  • memmove()
    • 舉例:

我們首先來考慮一個簡單的問題,我們定義了一個字元串,然後想要複制這個字元串,在C語言中,我們可以用

for循環

指針

來實作,假如我們用指針來操作

#include <stdio.h>

char  str1[20]= "Zxiaoxuan";
char  str2[20];
char * pts1 = str1 ;
char * pts2 = str2;

int main () {
	pts2=pts1;
	return  0;
}
           

這樣pts2隻是複制字元串str1的位址,而不是複制整個字元串。

那麼如何進行整個字元串的複制呢

  1. 我們可以采用數組的方式來進行
#include<stdio.h>

void copy_string(char str1[],char str2[]) {
	int i = 0;
	while(str2[i] != '\0') {
		str1[i] = str2[i];
		i++;
	}
	str1[i] = '\0';
}

int main() { 
	char a[100]="zxiaoxuan"; 
    char b[100]=" ";

	copy_string(b,a);
	printf("%s\n",b);
	return 0;
}
           

輸出:

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

2. 可以采用指針的方式來進行

#include<stdio.h>

void copy_string(char *p1,char *p2) {
	while(*p2 != '\0') {
		*p1 = *p2;
		*p1++;
		*p2++;
	}
	*p1 = '\0';
}
int main() {
	char a[100]="zxiaoxuan";
	char b[100]=" ";

	copy_string(b,a);
	printf("%s\n",b);
	return 0;
}
           

輸出:

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

除了上面兩種,C語言有沒有内置的函數來進行拷貝複制呢,當然是有的,下面我們來逐一介紹。

strcpy()

使用頭檔案:#include <string.h>

定義:char *strcpy(char *dest, const char *src);

參數:

destinin:目标字元數組;

source:源字元數組;

函數說明:strcpy()會将參數src 字元串拷貝至參數dest 所指的位址。 用于對字元串進行複制,識别到字元串的結束符号‘\0’自動停止

傳回值:傳回參數dest 的字元串起始位址。

注意:

  • 參數 dest 的記憶體空間要足夠大,否則拷貝可能會造成緩沖溢出。
  • strcpy() 在複制結束後會添加結束符

    \0

    ,這點和

    strncpy()

    不同

strcpy()

的參數是兩個字元串指針,其中

*src

源字元串可以是指針,數組名,或者字元串常量,但是

*dest

目标字元串必須位一個确定的資料對象(字元數組),而且應該已經開辟好了存儲空間(已經做好初始化)

舉例:

#include <stdio.h>
#include <string.h>
int main ()
{
    char  str1[]= "Zxiaoxuan";
    char  str2[20];
    char  str3[20];
    strcpy  (str2,str1);
    strcpy  (str3, "copy successful");
    printf  ( "str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
    return  0;
}

           

輸出:

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

memcpy()

使用頭檔案:C語言:#include <string.h> C++:#include<cstring>

定義:void memcpy(void *dest, const void *src, size_t n);

參數:

destinin:目标位址;

source:源位址;

n:複制的位元組長度。

函數說明:memcpy()複制 src 所指的記憶體資料的 n 個位元組到 dest所指的記憶體位址上。也就是從源位址複制n 個位元組到目标位址

第一個和第二個指針都是void型且第二個指針不能被修改,第三個參數是需要拷貝的記憶體長度按位元組記。

傳回值:傳回指向 dest 的指針。傳回的指針類型是void。

注意:

  • memcpy()并不限制被複制的資料類型,隻是逐位元組地進行複制,任何資料類型都可以進行複制,例如字元數組、整型、結構體、類等
  • memcpy() 會完整的複制 num個位元組,不會遇到‘\0’而結束,這點與 strcpy() 不同
  • dest 和 src所指的記憶體空間位址不能重疊
  • 參數 dest 的記憶體空間要足夠大,起碼要大于等于 num個位元組
  • 通常在複制字元串時用strcpy,而需要複制其他類型資料時則一般用memcpy

舉例:

#include  <string.h>
#include  <stdio.h>
#include  <stdlib.h>

#define N (20)

int main() {
	char *p1 = "zxiaoxuan";
	char *p2 = (char *)malloc(sizeof(char) * N);
	memcpy(p2, p1, N);

	printf("p2 = %s\n", p2);


	system("pause");
	return 0;
}
           
【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

strncpy()

使用頭檔案:#include <string.h>

定義:char *strncpy(char *dest, const char *src, size_t len);

參數:

destinin:目标字元數組;

source:源字元數組;

len:複制的字元串長度。

函數說明:strncpy()複制字元串 src 的前 len 個位元組到 dest所指的記憶體位址上。

傳回值:傳回字元串dest

注意:

  • strncpy()在複制結束後不會向dest結尾添加’\0’結束符 這個是很重要的一個點,要記住
  • 如果

    source(源字元數組)

    的長度>

    複制的字元串數len

    ,則隻複制

    source(源字元數組)

    的前len個字元,不會自動添加結束符

    \0

  • 如果

    source(源字元數組)

    的長度<

    複制的字元串數len

    ,則以

    NULL

    填充

    dest(目标字元數組)

    ,直到複制完n個位元組
  • 參數 dest 的記憶體空間要足夠大,起碼要大于等于 num個位元組
  • 在使用strncpy()的時候,拷貝長度最好為

    strlen(src)+1

    ,以保證最後的結束符

    \0

    也能被複制

舉例:

#include <stdio.h>
#include <string.h>

int main () {

	char str1[]= "Z Xiao Xuan";
	char str2[40];
	char str3[40];
	/* 拷貝到緩沖區: */
	strncpy ( str2, str1, sizeof(str1)+1); //拷貝長度為 str1+1,将結束符\0也進行拷貝

	/* 拷貝 5 個字元: */
	strncpy ( str3, str2, 5 );
	str3[5] = '\0';   /* 手動加上終止符 */

	puts (str1);
	puts (str2);
	puts (str3);

	system("pause");

	return 0;
}
           
【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

memmove()

使用頭檔案:#include <string.h>

定義:void *memmove( void* dest, const void* src, size_t count );

參數:

destinin:目标位址;

source:源位址;

count:複制的位元組長度。

函數說明:memmove()複制 src 所指的記憶體資料的 n 個位元組到 dest所指的記憶體位址上。也就是從源位址複制n 個位元組到目标位址。如果目标區域和源區域有重疊的話,memmove能夠保證源串在被覆寫之前将重疊區域的位元組拷貝到目标區域中,但複制後源内容會被更改。但是當目标區域與源區域沒有重疊則和memcpy函數功能相同。

緩沖區重疊這個需要講解一下:

根據

dest(目标字元數組)

記憶體區域和

src(源字元數組)

記憶體區域可分為三種情況:

    1. src記憶體區域和dest記憶體區域完全不重疊
【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()
    1. src(源字元數組)

      記憶體區域和

      dest(目标字元數組)

      記憶體區域存在重疊 且dest所在區域在src所在區域前
      【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()
      如上圖,

      dest(目标字元數組)

      src(源字元數組)

      存在三個位元組的記憶體區域重疊

但是在複制的時候,先把src的前三個位元組複制到了dest的前三個記憶體區域内,再繼續複制到重疊區域時,就算被覆寫,也不會有資料錯誤 是以這樣可以正常複制

    1. src(源字元數組)

      記憶體區域和

      dest(目标字元數組)

      記憶體區域存在重疊,且在dst所在區域在src所在區域後面
      【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()
      這時候如果使用memcpy()進行複制,會把三個重疊記憶體位元組覆寫為src的前三個位元組内容,導緻複制到重疊部分的時候出現錯誤

如果使用memmove(),會先将

src(源字元數組)

中的内容複制到緩沖區,然後再複制到

dest(目标字元數組)

中去,有效的避免了資料重疊。

舉例:

下面舉一個例子:

首先定義一個字元串str:

memmove can be very useful......

然後把字元串的第15個位元組~第25個位元組的11個位元組資料,複制到第20個位元組~第30個位元組中去

src(源字元數組)

very useful

dest(目标字元數組)

useful.....

重疊部分: 第20個位元組~第25個位元組

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {
	char str[] = "memmove can be very useful......";
	memmove (str+20,str+15,11);
	puts (str);

	system("pause");
	return 0;
}
           

先将11個位元組的

src(源字元數組)

資料(

very useful

)内容複制到緩沖區中,再用緩沖區中的内容覆寫

dest(目标字元數組)

指向的記憶體(第20個位元組~第30個位元組),這樣就避免了第20個位元組~第25個位元組的重疊

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

最後就變成了

memmove can be very very useful.

【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()
【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()
【C/C++】C語言複制字元串及複制函數彙總(strcpy()/memcpy()/strncpy()/memmove())strcpy()memcpy()strncpy()memmove()

繼續閱讀