strstr(字符串里查找字符串)
语法格式
![](https://img-blog.csdnimg.cn/direct/13cc3fe2b4e64bd490713d6abe9f3699.png)
库函数实现的逻辑
1,返回一个指向str2在str1中第一次出现的位置,如果str2不是p,则返回一个空指针,函数返回字符串str2在字符串str1中第一次出现的位置)
2,匹配过程不包括终止的空字符,但它将停止
举例
这里是arr1里面有没有出现p这个字符
这里是找到了
![](https://img-blog.csdnimg.cn/direct/27a700d2f3b54ad5a6e741c54fe0ce28.png)
![](https://img-blog.csdnimg.cn/direct/bd0e8fdf6b474a39b84a39d38e3b6774.png)
举例2
没有找到
![](https://img-blog.csdnimg.cn/direct/f08318142b824d4f8b3fc376b0abd067.png)
返回类型是char*
接收数值来一个
在(1,3)
1里面寻找有没有3
模拟strstrhanhsu
![](https://img-blog.csdnimg.cn/direct/497678944b414d1f995f847c62cf913e.png)
这里是不希望被修改的 所以加上const 这样就不能修改了
![](https://img-blog.csdnimg.cn/direct/b7d827e31f9143e2a332944f370fd70b.png)
这里我们分析查找的时候的多种情况
![](https://img-blog.csdnimg.cn/direct/aa0b6fdd1b2d46d5b7a45defac090bfe.png)
第一种情况的实现
![](https://img-blog.csdnimg.cn/direct/c564f3bbacb34a9e834b5406c4cba2da.png)
![](https://img-blog.csdnimg.cn/direct/98a3afdf1281416c8cb8fe1d1075c474.png)
![](https://img-blog.csdnimg.cn/direct/d751dcc2d44b4f2d936c232919a706a0.png)
![](https://img-blog.csdnimg.cn/direct/6333da786f6c494f878ef4f27e4b7b53.png)
![](https://img-blog.csdnimg.cn/direct/e3acb2efe9264bab910c392b7a530bdf.png)
第二种情况的实现
![](https://img-blog.csdnimg.cn/direct/614e7b9b798c445b9d6744146f79f0bb.png)
![](https://img-blog.csdnimg.cn/direct/b1532e572eaa43c2988785f1692d49d1.png)
![](https://img-blog.csdnimg.cn/direct/6d44385496f141f4827f51bdf5be9472.png)
![](https://img-blog.csdnimg.cn/direct/4003e2eec85946bd8a199e65dbfd8956.png)
![](https://img-blog.csdnimg.cn/direct/ada080f0a0894376844b5fad74723c50.png)
![](https://img-blog.csdnimg.cn/direct/e0b82aff12fb431b885fe3d493765892.png)
![](https://img-blog.csdnimg.cn/direct/19080030097d42af976e0b39ea5b4ed1.png)
这里需要总有一个指针指向初始的位置
![](https://img-blog.csdnimg.cn/direct/92c16f82f18a4f21b1ceec9ac4318d80.png)
![](https://img-blog.csdnimg.cn/direct/7f8a5e90a417426fbacca422c97058d3.png)
一个指针记录到哪里
还有一个指针记住从哪开始匹配
![](https://img-blog.csdnimg.cn/direct/f6fd072ff376437db19ab369dc7ebcf1.png)
这里进行比较 不相等 cur向后走一步
![](https://img-blog.csdnimg.cn/direct/8f0f9e8f060d4dd0811180b68a62d0ad.png)
![](https://img-blog.csdnimg.cn/direct/ecb45185a5474882b3a7c452e5a107da.png)
![](https://img-blog.csdnimg.cn/direct/bae2bfea3d08456ebbb9a49ecea3093b.png)
![](https://img-blog.csdnimg.cn/direct/a1ecf57855ad4f03b4928d1fd87b3a3a.png)
也就是开始尝试匹配 这个需要一个指针进行记录 这里的记录指针是不动的
这里是对比的函数里面是不遇见0 的
![](https://img-blog.csdnimg.cn/direct/d744866e3fe74ba19a0b25510718820b.png)
但是这里需要知道的是 *s2 等于\0的时候 也就找完了(找得到)
![](https://img-blog.csdnimg.cn/direct/205d1ed9fbb344b4bda32c7da53f76b6.png)
最后找不到 也就是遍历结束的时候 跳出循环 所以 此时也就返回空指针
![](https://img-blog.csdnimg.cn/direct/4c9e97e446d244bfb3815a9838de2dcc.png)
但是这还需要知道 如果arrr2是空字符串(进行特殊场景处理)但是需要强制类型转化 (因为是空指针)
![](https://img-blog.csdnimg.cn/direct/a991b0fe300642be86711dd6acb89c72.png)
在循环条件里面已经限制arr1比arr2小了
![](https://img-blog.csdnimg.cn/direct/69c7402e76864427a65c331c07fcdf3b.png)
上述的模拟是暴力查找 也就是不讲究效率的问题
这里说明一下 这里虽然初始化为空指针 但是没有对他使用 所以就相当于一条野狗先拴住 不靠近 用的时候再进行赋值
![](https://img-blog.csdnimg.cn/direct/fe38b49440f645c5a70ece3863185868.png)
kmp算法(解决的也是字符串里面寻找字符串)(实现和理解更复杂)(有兴趣研究一下)
![](https://img-blog.csdnimg.cn/direct/44628afd8ad74e97b5f53c6e10b8f021.png)
![](https://img-blog.csdnimg.cn/direct/3700a473124d420081b39a1fb5f176d4.png)
strstr函数模拟的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
//strstr函数的模拟
char* my_strstr(const char* arr1, const char* arr2)
{
assert(arr1 && arr2);//这里防止是传参过来的是空指针 进行一个断言
const char* s1 = NULL;
const char* s2 = NULL;
//这里需要创建两个指针变量 一个负责指向开始的位置 一个负责移动如果不满足条件的情况下 需要返回新的循环继续开始循环 直到遇见 或者循环结束
if (*arr2 == '\0')//这里首先判断是不是直接传过来空的字符 是的话 直接返回
return (char*)arr1;//这里是进行一个强制类型转化 因为 const是
//对于const存在的变量,通常不需要进行显式的类型转换,因为它的值是固定的。
// 然而,如果你需要将const变量用于不同的类型或者接口,你可能需要进行类型转换。
// 这通常涉及到将const变量指向的内存地址转换为其他类型指针,或者将它的值转换为其他格式或类型。
while (*arr1)//这里首先是指向数组 也就是只要数组循环不结束 也就一直寻找 下面会进行数组首元素的++ 这里解应用是因为补解应用就是地址 我们是寻找元素的
{
s1 = arr1;//这里进行赋值 把之前的空指针进行等于两个指针变量,也就是此时也就可以满足一个进行移动 一个进行计数 到那个位置了
s2 = arr2;//这里进行赋值 把之前的空指针进行等于两个指针变量,
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)//这里的循环条件是 只要每次对比的一样 并且不遇见最后一个字符'\0'就继续循环
{
s1++;//这里如果 s2 是三个字符 也就是循环三次 三次结束没有找到 s2也就是也就不等于s1了 此时也就跳出循环了
s2++;//然后 此时*arr1原本指向的字符如果是首元素 s1循环结束之后指向的是首元素+3个字符 这个时候没有满足条件 然后s1这个时候也就没有什么作用了 重新赋值所以arr++ 也就变成第二个元素 重新进行计算
}
if (*s2 == '\0')//这里是当对比字符串循环结束的时候 说明找到了元素 也就可以进行返回数值了
{
return (char*)arr1;//这里是找到这个元素所在位置 然后进行强制转化 把数值传递过去 传递的是开始找到的元素的位置 然后打印
}
arr1++;//这里是训话每次结束之后 进行++ 也就是元素向后移动一位 集训进行对比
}
return NULL;//如果最后循环结束 还没找到 此时也就返回空指针
}
//strstr函数的使用和模拟
int main()
{
char arr[] = "a b bbc def\n";
const char *p1 = "bbc";
char* ret = strstr(arr, p1);//这里是一个strstr函数的使用
if (p1==NULL)
printf("没找到。\n");
else
printf("找到了:%s\n", ret);
char arr1[] = "abbbcdef\n";
const char* p2 = "bbc";
char* re = my_strstr(arr1, p2);
if (p2 == NULL)
printf("没找到。");
else
printf("找到了:%s\n", re);
printf("找到了:%s\n", arr1);
return 0;
}
![](https://img-blog.csdnimg.cn/direct/528c92eb43d14c05bf57bf9ad01024a3.png)
|