C語言實(shí)現(xiàn)常用字符串庫函數(shù)(推薦)
一、實(shí)現(xiàn)memcpy
將src所指向的內(nèi)容拷貝到dst所指向的位置,拷貝len個(gè)字節(jié)。
- memcpy是內(nèi)存拷貝函數(shù)
- memcpy在使用的時(shí)候不用考慮類型,以字節(jié)為單位進(jìn)行拷貝
- 遇到"\0"的時(shí)候不會(huì)停下,所以拷貝字符串的時(shí)候最好還是用strcpy,它更安全。
void *Mymemcpy(void * dst, const void * src, int len){ void *ret = dst; assert(src); assert(dst); while (len--){ *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return ret; } int main(){ char str[100] = "ABCDE"; Mymemcpy(str, str + 2, 2); printf("%s", str); system("pause"); return 0; }
但是當(dāng)我們修改了測(cè)試用例后發(fā)現(xiàn)了如下結(jié)果
出現(xiàn)這種情況的原因很簡(jiǎn)單,因?yàn)槲覀冊(cè)醋址氖椎刂返陀谀繕?biāo)字符串的首地址,當(dāng)我們默認(rèn)從左向右拷貝的時(shí)候第一個(gè)字符串會(huì)覆蓋第二個(gè)字符串,所以出現(xiàn)了全A的情況,這就是內(nèi)存重疊拷貝,要解決這個(gè)問題非常簡(jiǎn)單,只需要在拷貝之前加一個(gè)判斷,如果源字符串的首地址低于目標(biāo)字符串的首地址則我們從右向左拷貝,這樣就可以完美解決這個(gè)問題。
二、memmove模擬實(shí)現(xiàn)
這里我們重復(fù)剛才的測(cè)試用例,發(fā)現(xiàn)加入了判斷并從右向左拷貝了之后沒有出現(xiàn)全A的情況。
void * Mymemmove(void * dst, const void *src, int len){ char *_src = (char*)src; char *_dst = (char*)dst; if (_dst > _src&&_dst < _src + len){ _dst = _dst + len - 1; _src = _src + len - 1; while (len--){ *_dst = *_src; _dst--; _src--; } } else { while (len--){ *_dst = *_src; _dst++; _src++; } } return dst; } int main(){ char str[100] = "ABCDE"; int len = strlen(str); memcpy(str+1, str , len); printf("%s", str); system("pause"); return 0; }
三、strlen的模擬實(shí)現(xiàn)
1.計(jì)數(shù)器方法:
int Mystrlen(char * str){ int count = 0; while (*str != 0){ str++; count++; } return count; } int main(){ char a[] = "dadai"; int aa=Mystrlen(a); printf("%d", aa); system("pause"); return 0; }
2.遞歸方式:
int Mystrlen(char * str){ if (*str == '\0'){ return 0; } else return (1 + Mystrlen(str + 1)); }//1+1+1+1+1+0 int main(){ char a[] = "dadai"; int aa=Mystrlen(a); printf("%d", aa); system("pause"); return 0; }
3.利用指針實(shí)現(xiàn):
int Mystrlen(char * str){ char *p = str; while (*p){ p++; } return (p - str); } int main(){ char a[] = "dadai"; int aa=Mystrlen(a); printf("%d", aa); system("pause"); return 0; }
四、strcpy的模擬實(shí)現(xiàn)
將src所指向的內(nèi)容拷貝到dst所指向的存儲(chǔ)單元。
char * Mycpy(char *dst, const char * src){ assert(dst != NULL && src !=NULL); char *Mycpy = dst; while((*dst++ = *src++) != '\0'); return Mycpy; } int main(){ char src []= "daadok"; char dst[10] ; Mycpy(dst, src); printf("%s", dst); system("pause"); return 0; }
五、strcmp的模擬實(shí)現(xiàn)
strcmp用于比較兩個(gè)字符串是否相等,若相等則返回0,若dst>src則返回1,否則換回-1.
int Mystrcmp(const char* dst,const char * src){ while (*dst&&*src&&(*dst == *src)){ dst++; src++; } if (*dst > *src){ return 1; } else if (*dst < *src){ return -1; } else if (*dst == *src){ return 0; } } int main(){ char str1[] = "abcdefg"; char str2[] = "dfd"; int a=Mystrcmp(str1, str2);; printf("%d", a); system("pause"); return 0; }
六、strstr模擬實(shí)現(xiàn)
在dst中找到第一次與src相等的位置并輸出這個(gè)位置之后dst所指向的內(nèi)容。
char *mystrstr( const char *dst,const char *src){ assert(dst); assert(src); const char *p = dst; while (*p){ const char *movep = p; const char *sp = src; while(*movep && *sp&& *sp== *movep){ sp++; movep++; } if (*sp == '\0'){ return (char *)p; } p++; } return NULL; } int main(){ const char* dst = "abcd123456"; const char*src = "cd"; char *ret= mystrstr(dst, src); printf("%s", ret); system("pause"); return 0; }
七、模擬實(shí)現(xiàn)strcat
把src所指向的內(nèi)容拼接到dst所指向內(nèi)容的末尾。
char * mystrcat(char*dst, const char*src){ assert(src); assert(dst); char*ret = dst; while (*dst){ dst++; } while (*src){ *dst = *src; dst++; src++; } return ret; } int main(){ char dst[64] = "abcd"; char *src = "efg"; mystrcat(dst, src); printf("%s", dst); system("pause"); return 0; }
到此這篇關(guān)于C語言實(shí)現(xiàn)常用字符串庫函數(shù)的文章就介紹到這了,更多相關(guān)C語言字符串庫函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于C++中數(shù)據(jù)16進(jìn)制輸出的方法
本文主要介紹了關(guān)于C++中數(shù)據(jù)16進(jìn)制輸出的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Qt基礎(chǔ)開發(fā)之QString與QByteArray詳細(xì)用法與區(qū)別及QString QByteArray互轉(zhuǎn)
這篇文章主要介紹了Qt基礎(chǔ)開發(fā)之QString與QByteArray詳細(xì)用法與區(qū)別及QString QByteArray互轉(zhuǎn),需要的朋友可以參考下2020-03-03C語言中調(diào)用Swift函數(shù)實(shí)例詳解
這篇文章主要介紹了C語言中調(diào)用Swift函數(shù)實(shí)例詳解的相關(guān)資料,實(shí)現(xiàn)該功能可以通過定義全局的指向Blocks的對(duì)象指針來實(shí)現(xiàn),需要的朋友可以參考下2017-07-07C語言安全編碼之?dāng)?shù)值中的sizeof操作符
這篇文章主要介紹了C語言安全編碼的數(shù)值中的sizeof操作符用法注意事項(xiàng),需要的朋友可以參考下2014-07-07C C++ 題解LeetCode2360圖中的最長(zhǎng)環(huán)示例
這篇文章主要為大家介紹了C C++ 題解LeetCode2360圖中的最長(zhǎng)環(huán)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Visual Studio Code配置C、C++環(huán)境并編寫運(yùn)行的方法
這篇文章主要介紹了Visual Studio Code配置C、C++環(huán)境并編寫運(yùn)行的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08