【C】strcpy strcat strlen strcmp等字符串函數的使用與說明

strlen

  • size_t strlen ( const char * str );
  • 作用:獲取字符串長度
  • 參數說明:傳入一個字符數組或者指向一個字符串的字符指針
  • 返回值:字符串長度

官方說明:C字符串的長度由終止的空字符決定:C字符串的長度等於字符串開頭和終止的空字符之間的字符數(不包括終止的空字符本身)。

測試程序

	char *test = "abcdef";
	int length = strlen(test);
	printf("字符串長度爲:%d\n",length);

output:字符串長度爲:6

模擬實現strlen方法

size_t mystrlen(const char * str){
    unsigned int count = 0;
    while (*str != '\0'){
        str++;
        count++;
    }
    return count;
}

特別說明:字符串末尾都是有一個終止字符的(’\0’),而strlen函數並不講終止字符計入字符串長度。

strcpy

  • char* strcpy ( char* destination, const char* source );
  • 作用:將source字符串複製進destination字符串中
  • 參數說明:
    • source:指向待複製內容的目標數組的字符指針
    • destination:指向將內容複製進入的數組的字符指針
  • 返回值:destination

官方說明:將源指向的C字符串複製到目標指向的數組中,包括終止的空字符(並在該點停止)。爲避免溢出,目標指向的數組大小應足夠長,以包含與源相同的C字符串(包括終止的空字符),並且不應在內存中與源重疊。

測試程序

	const char *source = "abcd";
	char destination[50] = "123456";
	strcpy(destination,source);
	puts(destination);

output:abcd

特別說明:上述程序的destination數組經過複製之後保存的數據爲:a b c d \0 6 \0,由於輸出時遇見終止字符’\0’便停止輸出,所以後面的6並不會輸出

模擬實現strcpy方法

char * mystrcpy(char * destination, const char * source){
	char *dst = destination;
    while (*source != '\0'){
        *destination = *source;
        destination++;
        source++;
    }
    *destination = '\0';
    return dst;
}

strcat

  • char* strcat ( char* destination, const char* source );
  • 作用:將源字符串接到目標字符串之後,形成新字符串
  • 參數說明:
    • source:源字符串
    • destination:目標字符串
  • 返回值:destination

官方說明:將源字符串的副本附加到目標字符串。目標中的終止空字符將被源的第一個字符覆蓋,並且在由目標中的兩個字符串聯而成的新字符串的末尾包含一個空字符。目的地和來源地不得重疊。

測試程序

	const char *source = "abcd";
	char destination[50] = "1234";
	strcat(destination,source);
	puts(destination);

output:1234abcd

特別說明:源字符串和目標字符串的地址不可相同

模擬實現strcat方法

char * mystrcat(char * destination, const char * source){
    char *dst = detination;
    while (*destination != '\0'){
        destination++;
    }
    while (*source != '\0'){
        *destination = *source;
        destination++;
        source++;
    }
    *destination = '\0';
    return dst;
}

strcmp

  • int strcmp ( const char* str1, const char* str2 );
  • 作用:比較兩個字符串的大小
  • 參數說明:str1和str2是待比較的兩個字符數組
  • 返回值:
    • 0:兩個字符串完全相同
    • 負數:str1中的ASCII值低於str2
    • 正數:str1中的ASCII值高於str2

官方說明:此函數開始比較每個字符串的第一個字符。如果它們彼此相等,則繼續比對,直到字符不同或達到終止的空字符爲止。

測試程序

	char* str1 = "abcd";
	char* str2 = "abcd";
	char* str3 = "efgh";
	printf("%d\n",strcmp(str1,str2));
	printf("%d\n",strcmp(str1,str3));
	printf("%d\n",strcmp(str3,str1));

output:
0
-1
1

模擬實現strcmp方法

int mystrcmp(const char * str1, const char * str2){
    while (*str1 != '\0'){
        if (*str1 > *str2){
            return 1;
        }
        else if (*str1 < *str2){
            return -1;
        }
        else{
            str1++;
            str2++;
            continue;
        }
    }
    return 0;
}

strncpy

  • char* strncpy ( char* destination, const char* source, size_t num );
  • 作用:選擇源字符串前num個字符複製到目標字符串中去
  • 參數說明:
    • source:源字符串
    • destination:目標字符串
    • num: 數量
  • 返回值:destination

官方說明:將源的前幾個字符複製到目標。如果在複製num個字符之前找到源C字符串的結尾,則用零填充目標,直到總共寫入num個字符爲止。
如果源的長度超過num,則在目標的末尾不會隱式追加空字符。因此,在這種情況下,目標不應被視爲以空結尾的C字符串(這樣讀取會溢出)。
目的地和來源地不得重疊(重疊時,參見memmove以獲得更安全的替代方案)。

測試程序

	char *source = "abcd";
	char destination[50] = "1234";
	strncpy(destination,source,3);
	puts(destination);

output:
abc4

	char *source = "abcd";
	char destination[50] = "1234";
	strncpy(destination,source,10);
	puts(destination);

output:
abcd

strncat

  • char* strncat ( char* destination, const char* source, size_t num );
  • 作用:將源字符串的num個字符接到目標字符串後面
  • 參數說明:
    • source:源字符串
    • destination:目標字符串
    • num: 數量
  • 返回值:destination

官方說明:將源的前幾個字符附加到目標,再加上一個終止的空字符。如果源中C字符串的長度小於num,則只複製不超過終止空字符的內容。

測試程序

	char *source = "abcd";
	char des[50] = "1234";
	strncat(des,source,2);
	puts(des);

output:
1234ab

	char *source = "abcd";
	char des[50] = "1234";
	strncat(des,source,6);
	puts(des);

output:
1234abcd

strncmp

  • int strncmp ( const char* str1, const char* str2, size_t num );
  • 作用:比較源字符串和目標字符串中前num個字符的大小
  • 參數說明:
    • str1和str2是待比較的兩個字符數組
    • num: 比較字符的數量
  • 返回值:
    • 0:兩個子字符串完全相同
    • 負數:子字符串中的ASCII值低於str2
    • 正數:子字符串中的ASCII值高於str2

官方說明:將C字符串str1的至多個字符與C字符串str2的最多個字符進行比較。
此函數開始比較每個字符串的第一個字符。如果它們彼此相等,則繼續使用以下對,直到字符不同,直到達到終止的空字符,或者直到兩個字符串中的num個字符匹配,以先發生的爲準。

測試程序

	char *s1 = "abcdABCD";
	char *s2 = "abcd1234";
	printf("%d\n",strncmp(s1,s2,4));
	printf("%d\n",strncmp(s1,s2,5));

output:
0
1

  char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
  int n;
  puts ("Looking for R2 astromech droids...");
  for (n=0 ; n<3 ; n++)
    if (strncmp (str[n],"R2xx",2) == 0)
    {
      printf ("found %s\n",str[n]);
    }

output:
Looking for R2 astromech droids…
found R2D2
found R2A6

strstr

  • char* strstr ( const char* str1, const char* str2);
  • 作用:尋找str2第一次在str1中出現的位置
  • 參數說明:
    • str1:包含待匹配字符串序列的字符串
    • str2:需尋找的字符串序列
  • 返回值:返回一個指針,指向str2整個字符串第一次在str1中出現的位置,如果str1不包含str2則返回空指針

官方說明:返回指向str1中第一個str2的指針,如果str2不是str1的一部分,則返回空指針。匹配過程不包括終止的空字符,但它在此停止。

測試程序

	char *s1 = "abcd1234";
	char *s2 = "12";
	char *s = strstr(s1,s2);
	puts(s);

output:
1234

模擬實現strstr

const char * strstr(const char * str1, const char * str2){
    while (*str1 != '\0'){
        if (*str1 == *str2){
            const char* pstr1 = str1;
            const char* pstr2 = str2;
            while (*pstr2 != '\0'){
                if (*pstr1 == *pstr2){
                    pstr1++, pstr2++;
                }
                else{
                    break;
                }
            }
            if (*pstr2 == '\0'){
                return str1;
            }
        }
        str1++;
    }
    return NULL;
}

strtok

  • char* strtok ( char* str, const char* delimiters );
  • 作用:按照某些分隔符將字符串分割成一個個子字符串
  • 參數說明:
    • str:待分割字符串
    • delimiters: 分隔符集合
  • 返回值:如果找到標記,則指向標記開頭的指針。否則,爲空指針。當掃描的字符串到達字符串的末尾(即空字符)時,總是返回空指針。

官方說明:
對此函數的一系列調用將str拆分爲標記,這些標記是由作爲分隔符一部分的任何字符分隔的連續字符序列。
在第一次調用時,函數需要一個C字符串作爲str的參數,str的第一個字符用作掃描標記的起始位置。在隨後的調用中,函數需要一個空指針,並使用最後一個標記結束後的位置作爲新的掃描起始位置。
要確定標記的開始和結束,函數首先從開始位置掃描分隔符中未包含的第一個字符(它將成爲標記的開始)。然後從標記的開頭開始掃描分隔符中包含的第一個字符,該字符將成爲標記的結尾。如果找到終止的空字符,掃描也會停止。
標記的這一端自動替換爲空字符,並且該函數返回標記的開頭。
一旦在對strtok的調用中找到str的終止空字符,對該函數的所有後續調用(以空指針作爲第一個參數)都將返回空指針。
找到最後一個標記的點由下一次調用時使用的函數內部保存(不需要特定的庫實現來避免數據競爭)。

測試程序
程序說明:將str字符串按照3個分隔符(,.-)分成子字符串

	char str[] ="- This, a sample string.";
	char * pch;
	printf ("Splitting string \"%s\" into tokens:\n",str);
	pch = strtok (str," ,.-");
	while (pch != NULL)
	{
		printf ("%s\n",pch);
		pch = strtok (NULL, " ,.-");
	}

output:
Splitting string “- This, a sample string.” into tokens:
This
a
sample
string

程序解釋:
在這裏插入圖片描述中間指針pch分別指向’T’、‘a’、‘s’、‘s’

strerror

  • char* strerror ( int errnum );
  • 作用:顯示errnum對應的錯誤信息
  • 參數說明:
    • errnum:錯誤編號
  • 返回值:根據錯誤編號返回相應的錯誤信息

解釋errnum的值,生成一個字符串,其中包含一條消息,該消息描述錯誤條件,就像庫的函數設置爲errno一樣。
返回的指針指向靜態分配的字符串,程序不應修改該字符串。進一步調用此函數可能會覆蓋其內容(不需要特定的庫實現來避免數據競爭)。
strerror生成的錯誤字符串可能特定於每個系統和庫實現。

測試程序
程序解釋:顯示Windows系統下所有錯誤編號對應的錯誤信息

	for (int i = 0; i < 44; i++)
	{
		printf("%d:%s\n", i, strerror(i));
	}

output:
0:No error
1:Operation not permitted
2:No such file or directory
3:No such process
4:Interrupted function call
5:Input/output error
6:No such device or address
7:Arg list too long
8:Exec format error
9:Bad file descriptor
10:No child processes
11:Resource temporarily unavailable
12:Not enough space
13:Permission denied
14:Bad address
15:Unknown error
16:Resource device
17:File exists
18:Improper link
19:No such device
20:Not a directory
21:Is a directory
22:Invalid argument
23:Too many open files in system
24:Too many open files
25:Inappropriate I/O control operation
26:Unknown error
27:File too large
28:No space left on device
29:Invalid seek
30:Read-only file system
31:Too many links
32:Broken pipe
33:Domain error
34:Result too large
35:Unknown error
36:Resource deadlock avoided
37:Unknown error
38:Filename too long
39:No locks available
40:Function not implemented
41:Directory not empty
42:Illegal byte sequence
43:Unknown error

由此可知Windows系統下一共有42個錯誤信息+1個無錯誤信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章