C语言:字符函数与字符串函数(一)
目錄
- 一、求字符串長度
- 1.1strlen
- 1.2注意:
- 二、長度不受限制的字符串函數
- 2.1strcpy
- 2.2strcat
- 2.3strcmp
- 三、長度受限制的字符串函數
- 3.1strncpy
- 3.2strncat
- 3.3strncmp
C語言中對字符和字符串有很多處理,但是C語言本身沒有字符串類型,字符串通常放在常量字符串中或者字符數組中。
字符串常量適用于那些對它不做修改的字符串函數。
一、求字符串長度
1.1strlen
求字符串長度
size_t strlen ( const char * str ); #include <stdio.h> int main() {int len = strlen("abcdef");printf("%d\n", len);return 0; }//6結果
上一篇寫strlen()函數的模擬實現中有3種方法:大齡失業學生轉碼日記:2022-12-02(strlen函數)
1、計數器的方法;
2、遞歸的方法;
3、指針-指針的方法
#include <assert.h> #include <stdio.h>//因為求的是字符串長度,不會改變str所指向字符串的內容,所以加const修飾, //即使str所指向的內容想要被修改也沒有機會了。 int my_strlen(const char* str) {//斷言:保證指針的有效性:assert(str != NULL);//用計數器的方法實現:int count = 0;while (*str != '\0')//或while(*str)都可以{count++;str++;}return count; } int main() {int len = my_strlen("abcdef");//表面傳的是字符串,實際傳的是字符串首字符地址。printf("%d\n", len);return 0; }結果
sizeof——是操作符,計算大小。sizeof計算的結果返回的類型是size_t;size_t 是專門為sizeof的返回值設計的。
size_t——其實是unsigned int類型,只表示正數。
strlen()函數返回的是無符號數,兩個無符號的數相減得到的也是無符號的數,比如下述代碼中會把-3當做無符號的數處理,是一個非常大的正數而會引入bug。
結果
strlen()的返回值可以寫成int類型,size_t類型或unsigned_int類型都可以。
上述代碼強制類型轉換為int可以得出“<=”:
#include <stdio.h> #include <string.h> int main() {if ((int)strlen("abc") - (int)strlen("abcdef") > 0){printf(">");}else{printf("<=");}return 0; }結果
1.2注意:
使用庫函數時需要包含頭文件,不包含會有bug。
使用strlen()函數時:
字符串以 ‘\0’ 作為結束標志,strlen函數返回的是在字符串中 ‘\0’ 前面出現的字符個數(不包
含 ‘\0’ )。
參數指向的字符串必須要以 ‘\0’ 結束。
函數的返回值為size_t,是無符號的。
二、長度不受限制的字符串函數
2.1strcpy
strcpy()函數用來拷貝字符串,會把源字符串內容拷貝到目標空間中,\0也會被拷貝過去。
char* strcpy(char * destination, const char * source );把arr1的內容拷貝放到arr2中
#include <stdio.h> #include <string.h> int main() {char arr1[] = "abcdef";char arr2[20] = { 0 };strcpy(arr2, arr1);printf("%s\n", arr2);return 0; }結果
注意:在使用strcpy()函數時:
源字符串必須以 ‘\0’ 結束。
會將源字符串中的 ‘\0’ 拷貝到目標空間。
目標空間必須足夠大,以確保能存放源字符串,防止造成越界訪問而使程序崩潰。
目標空間必須可變。
程序會崩潰,拷貝內容混亂
可以改為如下寫法
結果
strcpy()函數可以將源字符串內容拷貝到已有數據的數組中。
注意:遇到\0的時候,打印也結束了。所以即使目標空間在\0(這里的\0是從源數據中拷貝的)后面還有數據也不能打印了。
結果
strcpy()函數的模擬實現:
結果
2.2strcat
把源字符串內容追加到目標字符串的后面。
char * strcat ( char * destination, const char * source );strcpy()函數是拷貝,覆蓋原來的數據。
strcat()函數是把源字符串內容追加到目標字符串的后面。
結果
原理:arr2找到arr1的‘\0’,把‘\0’覆蓋掉然后拷貝arr2的內容。這里arr2是源字符串,‘\0’不會拷貝。
源字符串并沒有以’\0’結束,程序崩潰
改為如下
結果
2.3strcmp
用來比較兩個字符串。比較的是對應位置上的字符的大小——比較的是字符的ASCII碼值。a、b、c、d……按照順序ASCII碼值依次增大。
int strcmp ( const char * str1, const char * str2 );標準規定:
第一個字符串大于第二個字符串,則返回大于0的數字;
第一個字符串等于第二個字符串,則返回0;
第一個字符串小于第二個字符串,則返回小于0的數字。
結果
比的不是長度。
“abcdef”;
“bbq”;
這兩個字符串對應的第一個字符比,a<b,則小的字符所在的字符串就小,大的字符所在的字符串就大。所以arr1<arr2。
如果是:
“abcdef”;
“abq”;
這兩個字符串對應的第一個字符相等,就比較第二個對應的字符,第二個字符相等就比較第三對……直到比較雙方的‘\0’。
結果
模擬實現strcmp()函數:
結果
‘\0’的ASCII碼值是0。
注意:兩個字符串是不能相減的,兩個字符串不能用等號來判斷是否相等,更不能相減。
錯誤代碼,"abq"表達式產生的是它的a的地址(首字符的地址);
"abc"表達式產生的是它的a的地址;
這兩個地址一定不相等,所以不能用等號比。
意思是這兩個地址相減比較的是地址,就不是比較的兩個字符串的內容是否相等了;
所以兩個字符串不能相加,不能相減。
如果兩個字符串是常量字符串,那么二者的地址是相同的;
但是如果是兩個字符串數組,即使字符串內容相同地址也不會相同,因為是兩個完全不同的空間。
總結:
1 strcpy()函數在拷貝的時候,直到把源字符串中的\0拷貝完之后才停止拷貝,即拷貝到\0。
2 strcat()函數在追加的時候,也只在乎\0的問題,追加到\0。
3 strcmp()函數比較字符串的時候不相等就結束,相等就比較到\0。
4 這三個函數在拷貝的時候并沒有考慮拷貝的長度,一直到\0,所以這三個函數均是長度不受限制的字符串函數,與字符串的長度沒有關系。這三者頭文件均是<string.h>。
三、長度受限制的字符串函數
3.1strncpy
拷貝num個字符從源字符串到目標空間。
如果源字符串的長度小于num,則拷貝完源字符串之后,在目標的后邊追加0,直到num個。
結果
如果長度不夠,會主動放上’\0’
結果
如果長度不夠,會主動放上’\0’
strncpy()函數相對較靈活,更可控、相對安全。
3.2strncat
把源字符串的num個字符追加到目標空間中。
char * strncat ( char * destination, const char * source, size_t num ); #include <stdio.h> #include <string.h> int main() {char arr1[20] = "hello";char arr2[] = "world";//把arr2中的world這5個字符追加到arr1中strncat(arr1, arr2, 5);printf("%s\n", arr1);return 0; }結果
結果
結果
結果
strncat追加后還是字符串,所以會在追加指定的幾個字符后主動自己加上\0,所以追加完就停止打印。
結果
結果
結果
注意:
1、遇到\0;
2、追加的數字小于源字符串長度時,追加完要追加的字符后就不追加了。
3.3strncmp
比較num個字符串大小。
int strncmp ( const char * str1, const char * str2, size_t num ); #include <stdio.h> #include <string.h> int main() {char arr1[] = "abcdef";char arr2[] = "abcqqqqqq";int ret = strncmp(arr1, arr2, 3);printf("%d\n", ret);return 0; }結果
結果
結果
總結:
strncpy()函數 —— 拷貝
strncat ()函數 —— 追加
strncmp()函數 —— 比較
這三者是長度受限制的字符串函數,頭文件均是<string.h>。
總結
以上是生活随笔為你收集整理的C语言:字符函数与字符串函数(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 那些难忘的维护之夜
- 下一篇: Flutter开发(十二):Flutte