库函数strstr的介绍及模拟实现(常规解法)
本文介绍了C语言中的strstr字符串查找函数及其实现原理。strstr函数用于在一个字符串中查找子字符串,返回首次出现位置的指针或NULL。文章首先说明了strstr的基本用法和参数,然后详细分析了三种查找情况:首字符匹配、部分匹配和不匹配。通过图示展示了指针移动的逻辑过程,并给出了完整的模拟实现代码,包括外层循环定位起始位置和内层循环进行字符匹配。最后提到更高效的KMP算法可供进一步研究。测试
strstr函数的介绍
strstr(string string)是用来查找字符串的函数,使用它需要包含头文件<string.h> 。 它包含两个参数,返回值类型为char*,在c++官网中对它的介绍是这样的:
由此我们可以知道,strstr是在字符串str里查找另一个字符串substr,如果找到了就返回在str中找到的substr首字符的地址,找不到就返回空指针。
strstr函数的使用
strstr函数的使用也是非常简单,代码如下:
#include<stdio.h>
//使用strstr函数所需包含的头文件
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcd";
//在arr1中查找子字符串arr2
char* p = strstr(arr1, arr2);
//找不到就返回空指针,找到了就返回arr2首字符在arr1中第一次出现的位置
if (p == NULL)
printf("找不到\n");
else
printf("%s\n", p);
return 0;
}
输出结果如下:
strstr函数的模拟实现
当我们要设计一个函数进行字符串查找的时候,要考虑的情况就多了,有三种情况:
str1和str2是用来指向两个字符串首字符的指针
情况1中两个字符串的首字符一样,str1和str2同步向下移就能完成字符串查找。
情况2中str1和str2指向的字符不相等,str1需要继续往下找,直到遇到*str1==*str2为止
然后str1和str2再同步往下移完成字符串查找
情况3相对1和2来说就比较复杂了,str1和str2指向的字符不相等,str1先向下移直到*str1==*str2
然后str1和str2同步向下移查找字符串
第一次查找字符串不成功,我们需要进行第二次查找,第二次字符串查找时str1和str2指向位置如图:
由图我们可以很明显的看出来,当我们需要进行不止一次字符串查找时,动str1和str2指向的位置显然不合理,所以我们可以定义三个指针,其中两个指针用于每次字符串查找,一个指针用来存储字符串arr1的元素地址(从首地址开始)。
进行字符串查找时我们的思路是这样的:设置外层循环while(* cur),每次循环结束后cur++,指向arr1的下一个字符,当*cur==*s2时,进入内层循环,内层循环主要用来进行字符匹配。
外层循环:
内层循环:
根据这个逻辑,在每次循环开头我们要把cur赋给指针s1,把str2赋给指针s2。
根据之前情况讨论的结果,我们知道,内层循环结束后,当s2指向\0时说明在字符串arr1中找到了字符串arr2,cur就是字符串arr2首字符在字符串arr1中出现的位置,直接返回cur。
我们希望跳出内层循环后s1和s2指针不会越界,所以加一个条件(s1&&s2)。
当查找字符串外层循环完全结束后,说明没有找到字符串,直接返回空指针NULL就行。
由于该函数不会改变两个字符串的内容,所以传过来的两个参数(char str1,char str2)和我们定义的三个指针都用const修饰相对比较安全,此外,我们在函数开头用assert断言可以确保传过来的两个指针的有效性(不要忘了头文件<assert.h>)。完整函数如下:
char* my_strstr(const char* str1,const char* str2)
{
assert(s1&&s2);
const char* s1 = NULL;
const char* s2 = NULL;
const char* cur = str1;
while (*cur)
{
//用于进行字符匹配
s1 = cur;
s2 = str2;
while ((*s1&&*s2)&& * s1 == *s2)
{
s1++;
s2++;
}
//s2指向\0,说明成功找到字符串
if (*s2 == '\0')
return cur;
cur++;
}
//查找字符串整体循环结束,说明没有找到,直接返回空指针
return NULL;
}
程序测试结果如下:

说明程序功能正常。
扩展
这是查找字符串的一种常规方法,对于查找字符串还有一种更高效的算法KMP,只是程序有点复杂,代码也难理解,有兴趣的可以去了解一下。
我写的文章如果有不足之处,欢迎指正~
更多推荐



所有评论(0)