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