通常看到strrchr这个函数,人们很自然的想问库里面有没有strrstr这个函数呢???
答案是:没有。
但是我们可以自己实现一个strrstr函数,它的功能是查找最后一次出现的子字符串,如果找打则返回这个地址,如果没找到则返回空地址。
实现方案:对于这个函数有两种实现方式。
第一种是从后向前找,第一次找到就返回这个地址。
第二种是从前向后找,用一个标签记录第一次找到的位置,然后当第二次找到时再更新这个标签,最后标签里面保存的地址就是我们要找的地址。
从后向前找:
#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<string.h> char *my_strrstr(const char *dst, const char *src) { assert(dst ); //对字符串进行断言,判断是否为空 assert(src ); const char *pdst = dst; const char *psrc = src; char *tmp = NULL ; while (*pdst) //因为要从后向前找,则首先让pdst指向'\0' { pdst++; } while (pdst >= dst ) //当pdst大于dst则表明dst这个字符串还没有找完 { if (tmp=(char *)strstr(pdst, psrc = src)) //使用strstr帮助寻找,找到保存到tmp return tmp; pdst--; } return NULL ; } int main() { char arr[30]; char arr1[20]; scanf( "%s%s", arr, arr1); char *ret=my_strrstr(arr, arr1); printf( "%#p\n", ret); system( "pause"); return 0; }
//当字符串很大时,效率很高
从前向后找:
char *my_strrstr(const char *dst, const char *src) { assert(dst ); assert(src ); const char *pdst = dst; const char *psrc = src; char *right= NULL ; while (*dst ) { while (*pdst == *psrc) { if (*pdst== '\0' ) //如果pdst指向'\0'则表明目标数组已经找完 return right=(char *)dst; else { pdst++; psrc++; } } if (*psrc == '\0' ) //src已经则dst中出现,将这个地址保存起来 right = (char *)dst ; pdst = ++ dst; psrc = src; } return right; } int main() { char arr1[50] = { 0 }; char arr2[40] = { 0 }; char *place = NULL ; scanf( "%s%s",arr1, arr2); place = my_strrstr(arr1, arr2); printf( "%#p\n",place); system( "pause"); return 0; }
//当目标字符串很大时,效率特别低
strtok:
功能: 可以将一个字符串按照分隔符分开读取
原型: char * strtok(char *str,const char *sep);
str是要读取的字符串,这个字符串里面包含了若干sep中的字符。sep指向分隔符字符串。strtok找到str中下一个标记,并用'\0'替换。
用法:
例:arr[]="ab@cd#ef$gh#"; sep[]="@#$".
将str按照sep中出现的分隔符分隔开来。如果参数arr非空,则strtok将找到第一个标记,将它赋成‘\0',并保存它的下一个位置。
第一次调用strtok(arr,sep);返回首地址,保存c的地址。
第二次调用strtok(NULL,sep);str参数为NULL,则strtok从c的位置寻找下一个分隔符。也就是找到#后将#换成'\0'并返回c的地址。
此后再调用strtok和第二次类似:如果str参数为NULL,则strtok就在同一个字符串中从上次保存的位置寻找下一个分隔符。
strtok实现:
char *my_strtok(char *dst, char const * sep) { assert(dst ); //断言字符串是否为空 assert(sep ); static char *pdst=NULL; //声明一个静态局部变量 char *origin = NULL ; if (dst ) pdst = dst; origin = pdst; //记录起始位置 while( !strchr(sep , *pdst)||*pdst) //寻找分隔符,当遇到'\0'程序结束 { pdst++; } if (*pdst) //如果找到分隔符 *pdst++ = '\0'; //将分隔符换成'\0' return origin; } int main() { char *ret = NULL ; char arr[20]; char *arr1="@#$" ; scanf( "%s", arr); for (ret = strtok(arr, arr1); ret != NULL; ret = strtok( NULL, arr1)) printf( "%s\n", ret); system( "pause"); return 0; }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。