C語言實現(xiàn)常用字符串庫函數(shù)(推薦)
一、實現(xiàn)memcpy
將src所指向的內(nèi)容拷貝到dst所指向的位置,拷貝len個字節(jié)。
- memcpy是內(nèi)存拷貝函數(shù)
- memcpy在使用的時候不用考慮類型,以字節(jié)為單位進行拷貝
- 遇到"\0"的時候不會停下,所以拷貝字符串的時候最好還是用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)我們修改了測試用例后發(fā)現(xiàn)了如下結(jié)果

出現(xiàn)這種情況的原因很簡單,因為我們源字符串的首地址低于目標(biāo)字符串的首地址,當(dāng)我們默認從左向右拷貝的時候第一個字符串會覆蓋第二個字符串,所以出現(xiàn)了全A的情況,這就是內(nèi)存重疊拷貝,要解決這個問題非常簡單,只需要在拷貝之前加一個判斷,如果源字符串的首地址低于目標(biāo)字符串的首地址則我們從右向左拷貝,這樣就可以完美解決這個問題。
二、memmove模擬實現(xiàn)
這里我們重復(fù)剛才的測試用例,發(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的模擬實現(xiàn)
1.計數(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.利用指針實現(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的模擬實現(xiàn)
將src所指向的內(nèi)容拷貝到dst所指向的存儲單元。
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的模擬實現(xiàn)
strcmp用于比較兩個字符串是否相等,若相等則返回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模擬實現(xiàn)
在dst中找到第一次與src相等的位置并輸出這個位置之后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;
}

七、模擬實現(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語言實現(xiàn)常用字符串庫函數(shù)的文章就介紹到這了,更多相關(guān)C語言字符串庫函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入探討Linux靜態(tài)庫與動態(tài)庫的詳解(一看就懂)
本篇文章是對Linux靜態(tài)庫與動態(tài)庫進行了詳細的分析介紹,需要的朋友參考下2013-05-05
win10環(huán)境下C++ vs2015編譯opencv249的教程
這篇文章主要介紹了win10環(huán)境下C++ vs2015編譯opencv249的教程,本文分步驟給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
C語言中的時間函數(shù)clock()和time()你都了解嗎
這篇文章主要為大家詳細介紹了C語言中的時間函數(shù)clock()和time(),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02

