摘要:源字符串不修改,所以用修飾找到目標空間的位置跳出循環時,指向的就是目標空間的位置,從該位置向后追加,相當于作用字符串比較函數,是比較字符串的庫函數,比較的是字符串的內容,不是長度。
?今天是2021年9月21日,首先祝大家中秋節快樂啦!但愿人長久,千里共嬋娟。又是一年月圓,祝大家在中秋節都能和你愛的人和愛你的人團圓~
接下來進入整體啦~
目錄
1.作用:求字符串長度
字符串以/0為結束標志,strlen()函數返回的是在字符串中‘/0’前面出現的字符個數(不包含/0)?
參數指向的字符串必須要以/0結尾
2.模擬實現:
方法1:計數器
size_t my_strlen(const char* str){ size_t count = 0; while (*str) { count++; str++; } return count;}int main(){ char* str = "Mango"; size_t count = my_strlen(str); printf("%u/n", count); return 0;}
方法2: 指針-指針
指針-指針->得到的是二者相差的元素的個數? 所以一個尾指針指向/0,一個指向起始位置,二者相減得到的就是字符串長度
size_t my_strlen(const char* str){ const char* start = str; const char* end = str; while (*end) { end++; } return end - start;}int main(){ char* str = "Mango"; size_t count = my_strlen(str); printf("%u/n", count); return 0;}
方法3:遞歸?
size_t my_strlen(const char* str){ //如果指向的不是/0,就+1(本身指向的字符),然后遞歸下一個字符 if (*str) { return 1 + my_strlen(str + 1); } //str指向的是/0就返回0 else { return 0; }}int main(){ char* str = "Mango"; size_t count = my_strlen(str); printf("%u/n", count); return 0;}
?
1.作用:字符串拷貝,strcpy:拷貝的是源字符串開始向后直到/0前的內容
注意點:
會將源字符串的/0拷貝到目標空間
目標空間必須足夠大,以確保能存放源字符串
目標空間必須可變
2.模擬實現
?注意點:源字符串不修改,所以用const修飾,返回類型為char*,返回的是目標空間的起始地址,所以定義一個指針保存起始地址,然后將src指向的內容拷貝到dest中
char* my_strcpy(char* dest,const char* src){ assert(dest&&src); char* ret = dest; //保存起始地址 while(*src) { *dest = *src; dest++; src++; } //上述只是完成了將src中/0之前的內容拷貝 //還要拷貝/0 *dest = *src; return ret;}int main(){ char arr1[] = "xxxxxxx"; char arr2[] = "Mango"; char* ret = my_strcpy(arr1,arr2); printf("%s/n",arr1); printf("%s/n",ret); return 0;}
簡易寫法:
char* my_strcpy(char* dest,const char* src){ assert(dest&&src); char* ret = dest; //保存起始地址 while(*dest++ = *src++) { ; } return ret;}
最后一次,src指向/0,把/0也拷貝過去之后,while判斷表達式為假,跳出循環。 ?
1.作用:字符串追加函數,從目標空間的/0位置開始向后追加源字符串
注意事項:
源字符串必須以/0結尾
目標空間也必須足夠大,能容納下源字符串的內容
目標空間必須可修改
不可以給自己追加!
2.模擬實現
思路:由于是在目標空間的/0位置開始向后追加,所以要先找到目標空間的/0位置,追加類似于strcpy過程,一個字符一個字符的追加,直到遇到源字符串的/0
注意:返回的是目標空間的起始地址,所以用指針變量保存它的地址。源字符串不修改,所以用const修飾
char* my_strcat(char* dest,const char* src){ assert(dest && src); char* ret = dest; //1.找到目標空間的/0位置 while (*dest) { dest++; } //跳出循環時,dest指向的就是目標空間的/0位置,從該位置向后追加,相當于strcpy while (*dest++ = *src++) { ; } return ret;}int main(){ char arr1[20] = "Mango"; char arr2[] = "Hello"; my_strcat(arr1, arr2); printf("%s/n", arr1); return 0;}
1.作用:字符串比較函數,strcmp 是比較字符串的庫函數,比較的是字符串的內容,不是長度。比較的是兩個字符串中,二者對應的第一個不相等字符的ascii碼值大小, 比較的是/0之前的字符
?2.模擬實現
思路:遍歷兩個字符串,對應位置的字符比較是否相等,找到第一個二者對應不相等的字符,解引用,比較其對應的ascii碼值
注意:當二者指向的字符相同時,判斷其中一個指向的是不是/0,如果是,說明這兩個字符串是一樣的,
兩個字符串只需要比較,不需要修改,所以用const修
int my_strcmp(const char* s1,const char* s2){ assert(s1 && s2); //當二者指向的字符相同時,繼續找,直到找到不相等的,或者其中一個為/0了,那就跳出循環 while(*s1 == *s2) { //先判斷其中一個是不是/0,如果是,說明兩個字符串是一樣的,二者都指向了/0 if(*s1 == "/0") { return 0; } s1++; s2++; } //找到指向不想等的字符了(或者一個為/0了),解引用比較對應的值 return *s1 - *s2;}int main(){ char arr1[] = "abcd"; char arr2[] = ""; int ret = my_strcmp(arr1, arr2); if (ret > 0) { printf("arr1 > arr2/n"); } else if (ret < 0 ) { printf("arr1 < arr2/n"); } else { printf("arr1 = arr2/n"); } return 0;}
1,作用:字符串追加函數,和strcat的區別:此函數可以限制追加多少字節的內容
?當要追加的長度大于(小于)源字符串長度時,追加至源字符串/0位置即停止追加,追加結束后放入/0
2.模擬實現
?思路:
1.找到目標空間的/0位置
2.進行拷貝,共拷貝n次,(注意:拷貝過程中,有可能源字符串提前遇到/0,或者要拷貝的長度比源字符串長度長)
3.進行判斷count是否還>0,如果還>0,說明提前遇到/0,或者源字符串長度比要拷貝的長度短。這樣的話,在目標空間追加完的下一個位置補/0
char* my_strncat(char* dest, char* src, size_t count){ assert(dest && src); char* tmp = dest; //1.找到目標空間/0位置 while (*dest!="/0") { dest++; } //跳出時,dest指向的就是/0,從此處開始拷貝 while (count-- && (*dest++ = *src++)) { ; } //追加結束后,補/0 //上面while拷貝完后,dest指向的是追加完成后的下一個位置,在此位置補/0 *dest = "/0"; return tmp;}int main(){ char arr1[20] = "Mango/0xxxxxx"; char arr2[] = "Lemon"; my_strncat(arr1, arr2, 2); printf("%s/n", arr1);}
?1.作用:
strncmp的功能和strcmp的功能和相似,只不過多了一個參數用來確定比較的個數
比較到出現另個字符不一樣或者一個字符串結束或者num個字符全部比較完
2.模擬實現
int my_strncmp(char* dest, char* src, size_t count){ assert(dest && src); //找到前count個字符中,不相等的字符 while (count) { count--; //二者指向相等,繼續往下找 if (*dest == *src) { //若二者相等,且都是/0,則返回0 if(*dest == "/0") { return 0; } dest++; src++; } else //二者指向不相等,跳出循環 break; } //跳出時,找到不想等的字符,或者二者相等 return *dest - *src;}int main(){ char* str1 = "abcdef"; char* str2 = "abcd"; int ret = my_strncmp(str1, str2, 3); if (ret > 0) { printf("str1>str2/n"); } else if (ret < 0) { printf("str1 < str2/n"); } else { printf("str1= str2/n"); } return 0;}
1.作用:?在一個主字符串找查找子字符串,如果找到了,反正子字符串在主字符串的起始位置,找不到,則返回空指針
注意:返回的是第一次出現的位置
2.模擬實現
?注意:遍歷兩個字符串進行比較,定義3個指針,一個指針用于遍歷主字符串,一個指針用于遍歷字符串,一個指針用于保存主串開始遍歷的位置(方便后序返回子串在主串的起始位置)
當子字符串走到/0時,說明找到了,
當主子符串走到/0時,要么主字符串和子字符串相等,要么就是找不到
當子字符串為空字符串時,返回主字符串的起始地址(庫函數就是這么寫的)
?圖解:
代碼:
//返回子串出現在主串的第一個位置char* my_strstr(const char* str1, const char* str2){ assert(str1 && str2); char* s1; //用來遍歷str1 char* s2; //用來遍歷str2 char* cp = str1; //用于保存主子符串開始遍歷的位置 //如果str2為空字符串,直接返回str1的地址 if (*str2 == "/0") { return str1; } //遍歷主串與子串比較 while (*cp) { s1 = cp; //s1從cp位置開始向后比較 s2 = str2; //s2回到原始位置 while ((*s1 == *s2)&&*s1&&*s2) //不僅要保證二者指向字符相等,還要保證s1和s2指向的不是/0 { s1++; s2++; } if (*s2 == "/0") { return cp; //返回子串在主串的起始位置 } else { //s1和s2指向不相等,cp指向下一個字符,然后下一次循環,把cp的值賦給s1用于下次遍歷 cp++; } } //跳出while循環時,說明主串都遍歷完了,說明找不到->返回NULL return NULL;}int main(){ char* str1 = "MangoLemon"; char* str2 = "an"; char* tmp = strstr(str1, str2); char* tmpp = my_strstr(str1, str2); printf("%s/n", tmp); printf("%s/n", tmpp); return 0;}
1.作用: 字符串切割
第二個參數是個字符串,定義了用作分割字符串的集合
strtok函數找到str中的下一個標記,并將其用/0結尾,返回一個指向這個標記的指針(注意:strtok函數會改變被操作的字符串,所以在使用strtok函數切分的字符串一般都是臨時拷貝的內容且可修改)
strtok函數的第一個參數不為NULL時:函數將找到str中第一個標記,strtok函數將保存它在字符串中位置
strtok的第一個參數為NULL時,函數將在同一個字符串中被保存的位置開始,查找下一個標志
如果字符串中不存在更多的標志,就返回NULL
?例子:
?
?
int main(){ char arr1[] = "Mango@Lemon.Jiayou"; char arr2[100] = {0}; //防止strtok函數改變arr1中的數據,使用臨時數組arr2 char sep[] = "@."; //分割字符串的集合,即遇到@ 或者.就分割字符串 strcpy(arr2,arr1); char* ret = NULL; //分割字符串 //注意:第一次傳傳參為arr2,后序傳參都傳NULL for(ret = strtok(arr2,sep); ret != NULL; ret = strtok(NULL,sep)) { printf("%s/n",ret); } //相當于 //char* ret2 =strtok(arr2, sep); //printf("%s/n", ret2); //ret2 =strtok(NULL, sep); //printf("%s/n", ret2);}
上述的函數中,
strcpy()? ? ? ? ?strcat()? ? ? ? ? strcmp()??
上述三個函數不夠安全 長度不受限制的字符串函數。要么就一直追加/拷貝,直到遇到/0,或者一直比較,直到遇到不相等的字符
strncpy()? ?strncat()? ?strncmp() ??
此三個函數可以控制字節數,相對安全!
?本文將持續更新那些博主今后遇到的其他的字符函數~歡迎關注!
如果感覺此文對你有幫助,請給博主一個三連吧!大家中秋節快樂!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/120820.html
摘要:本文介紹了類的常用接口的使用,并對其進行了模擬實現,對模擬實現中涉及到的深淺拷貝問題進行了解析。在此之前,必須提到一個經典問題。為了解決淺拷貝問題,所以中引入了深拷貝。但是實際使用中需要是第一個形參對象,才能正常使用。 本文介紹了string類的常用接口的使用,并對其進行了模擬實現,對模擬實...
前言:博主之前有已經寫過了C語言常用字符函數詳解+模擬實現,感興趣的同學可以去圍觀一下哦! 目錄 前言: 1.內存函數 memcpy() ?memmove() memcmp() memset() 2.錯誤信息報告函數 strerror() ?perror() 1.內存函數 memcpy() 作用:內存拷貝 函數原型: 注意:count:要拷貝的字節數 函數memcpy從src位置開始向后賦值c...
摘要:自己實現時返回值可根據實際情況而定源字符串必須以結束。語言中給了一些長度受限的字符串函數,而前面的函數是長度不受限的字符串函數。拷貝個字符從源字符串到目標空間。 目錄 字符函數和字符串函數 函數介紹 strlen strcpy strcat strcmp strncpy ?strncat s...
摘要:四函數字符串追加函數介紹函數的返回值類型為,可以返回被追加的字符串的起始地址。利用函數所需的頭文件函數的使用代碼運行結果為函數的特點及注意事項源字符串必須以結束。目標空間必須有足夠的大,能容納下源字符串的內容。 ...
摘要:目錄一函數是什么二使用排序以升序為例關于型指針整形數組排序字符數組排序字符指針數組排序結構體數組排序浮點型數組排序三使用冒泡排序思想模擬實現函數什么是冒泡排序冒泡排序代碼使用冒泡排序思想模 目錄 一.qsort函數是什么 ?二.使用qsort排序-以升序為例 ? ? ??關于void*型指針...
閱讀 1618·2021-11-22 13:53
閱讀 2848·2021-11-15 18:10
閱讀 2755·2021-09-23 11:21
閱讀 2491·2019-08-30 15:55
閱讀 474·2019-08-30 13:02
閱讀 752·2019-08-29 17:22
閱讀 1658·2019-08-29 13:56
閱讀 3454·2019-08-29 11:31