大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
函数原型
const char * strstr ( const char * str1, const char * str2 );
需要的头文件string.h
从原型可以看出它的返回值为const char*一个字符类型的常量指针
参数
str1
要扫描的字符串
str2
包含要查找的字符串
括号里要传入的值也是两个指针,也用了const修饰,为什么是常量等到下面模拟实现时再进行说明
使用方法直接上代码说明
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "Hello World"; //要扫描的字符串。
char str2[] = "llo"; //要查找的字符串
char* a = strstr(str,str2);
if (a != NULL)
{
printf("%s\n", a);
printf("%p\n", a);
}
else if (a == NULL)
{
printf("没有找到");
printf("%p\n", a);
}
}
看看结果
第一个结果为要查找的字符串 的 第一个字符往后的所有内容
下面的结果是这个a储存的地址.
这个地址是什么呢?也直接用代码来说明下
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "Hello Worldllo"; //要扫描的字符串。
char str2[] = "llo"; //要查找的字符串
printf("%p\n",&str[2]);//打印一下 被查找字符串 中 要查找字符串 的第一个字符出现的地址
char* a = strstr(str,str2);
if (a != NULL)
{
printf("%s\n", a);
printf("%p\n", a);
}
else if (a == NULL) //a == NULL就打印
{
printf("没有找到");
printf("%p\n", a);
}
}
看看结果
可以看到 要扫描的字符串中 与 要查找的的字符串 的第一个字符出现的地址与strstr的返回值一样这就说明了strstr返回的就是 要查找的字符串 第一个 字符出现的地址,后面的后面还有一个 “llo” strstr就不理了它只找一次就罢工了,有点懒
下面来看看搜索不到的情况
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "Hello World"; //要扫描的字符串
char str2[] = "lll"; //要查找的字符串
char* a = strstr(str,str2);
if (a != NULL)
{
printf("%s\n", a);
printf("%p\n", a);
}
else if (a == NULL) //a == NULL就打印
{
printf("没有找到\n");
printf("%p\n", a);
}
}
看看结果
没找到就直接返回一个空指针了
下面来模拟实现下strstr
直接上代码
#include<stdio.h>
const char* sstrstr(const char* str, const char* str2)
{
int i = 0;
int j = 0; //用于循环要查找的数组
while(*(str + i) != '\0')
{
if (*(str + i) == *(str2 + j)) //进行判断 如果开始等于了进入下面的循环
{
while (1) //这里不会死循环的,下面有终止条件,不用担心
{
if (*(str + i) == *(str2 + j)) //进行判断如果还等于,就继续循环
{
i++;
j++;
if (*(str2 + j) == '\0') //判断如果 要查找的字符串 循环完了就返回它第一个字符出现的地址
{
return (str + i - j); //可能还有人不懂,这里再进行说明函数只要一遇到return就会直接停止,整个函数停止
}
}
else if(j == 1) //如果j只加了一次就只需j置为0就行,为什么呢?下面用文字说明,代码里不说那么多
{
j = 0;
break;
}
else //其他情况就i - 1,同时j也要置为0;
{
i = i - 1;
j = 0;
break;
}
}
}
else //什么都没找到i++继续找就完事了
{
i++;
}
}
return NULL; //如果没找到就返回空指针
}
int main()
{
char arr[] = "acccbbbcbbbcddddddddd";
char arr2[] = "cbbb";
char* a = sstrstr(arr, arr2); //a用于接收返回的值
if (a != NULL)
{
printf("%s\n", a);
}
else if (a == NULL) //a == NULL就打印
{
printf("没有找到");
}
}
跑下看看结果
结果正确
看看没找到的情况
#include<stdio.h>
const char* sstrstr(const char* str, const char* str2)
{
int i = 0;
int j = 0; //用于循环要查找的数组
while(*(str + i) != '\0')
{
if (*(str + i) == *(str2 + j)) //进行判断 如果开始等于了进入下面的循环
{
while (1) //这里不会死循环的,下面有终止条件,不用担心
{
if (*(str + i) == *(str2 + j)) //进行判断如果还等于,就继续循环
{
i++;
j++;
if (*(str2 + j) == '\0') //判断如果 要查找的字符串 循环完了就返回它第一个字符出现的地址
{
return (str + i - j); //可能还有人不懂,这里再进行说明函数只要一遇到return就会直接停止,整个函数停止
}
}
else if(j == 1) //如果j只加了一次就只需j置为0就行,为什么呢?下面用文字说明,代码里不说那么多
{
j = 0;
break;
}
else //其他情况就i - 1,同时j也要置为0;
{
i = i - 1;
j = 0;
break;
}
}
}
else //什么都没找到i++继续找就完事了
{
i++;
}
}
return NULL; //如果没找到就返回空指针
}
int main()
{
char arr[] = "acccbbbcbbbcddddddddd";
char arr2[] = "cbcb";
char* a = sstrstr(arr, arr2); //a用于接收返回的值
if (a != NULL)
{
printf("%s\n", a);
}
else if (a == NULL) //a == NULL就打印
{
printf("没有找到\n");
}
}
康康结果
结果正确!
下面我单独分出这个函数,来进行说明
#include<stdio.h>
const char* sstrstr(const char* str, const char* str2)
{
int i = 0;
int j = 0; //用于循环要查找的数组
while(*(str + i) != '\0')
{
if (*(str + i) == *(str2 + j)) //进行判断 如果开始等于了进入下面的循环
{
while (1) //这里不会死循环的,下面有终止条件,不用担心
{
if (*(str + i) == *(str2 + j)) //进行判断如果还等于,就继续循环
{
i++;
j++;
if (*(str2 + j) == '\0') //判断如果 要查找的字符串 循环完了就返回它第一个字符出现的地址
{
return (str + i - j); //可能还有人不懂,这里再进行说明函数只要一遇到return就会直接停止,整个函数停止
}
}
else if(j == 1) //如果j只加了一次就只需j置为0就行,为什么呢?下面用文字说明,代码里不说那么多
{
j = 0;
break;
}
else //其他情况就i - 1,同时j也要置为0;
{
i = i - 1;
j = 0;
break;
}
}
}
else //什么都没找到i++继续找就完事了
{
i++;
}
}
return NULL; //如果没找到就返回空指针
}
代码挺长的
看到 i 减 1 那段注释为什么i 要减1呢我们下面用代码说明
我们看看把 i – 1 去掉看看会发生什么
#include<stdio.h>
const char* sstrstr(const char* str, const char* str2)
{
int i = 0;
int j = 0; //用于循环要查找的数组
while(*(str + i) != '\0')
{
if (*(str + i) == *(str2 + j)) //进行判断 如果开始等于了进入下面的循环
{
while (1) //这里不会死循环的,下面有终止条件,不用担心
{
if (*(str + i) == *(str2 + j)) //进行判断如果还等于,就继续循环
{
i++;
j++;
if (*(str2 + j) == '\0') //判断如果 要查找的字符串 循环完了就返回它第一个字符出现的地址
{
return (str + i - j); //可能还有人不懂,这里再进行说明函数只要一遇到return就会直接停止,整个函数停止
}
}
else if(j == 1) //如果j只加了一次就只需j置为0就行,为什么呢?下面用文字说明,代码里不说那么多
{
j = 0;
break;
}
else //其他情况就i - 1,同时j也要置为0;
{
j = 0;
break;
}
}
}
else //什么都没找到i++继续找就完事了
{
i++;
}
}
return NULL; //如果没找到就返回空指针
}
int main()
{
char arr[] = "acccbbbcbbbcddddddddd";
char arr2[] = "ccb";
char* a = sstrstr(arr, arr2); //a用于接收返回的值
if (a != NULL)
{
printf("%s\n", a);
}
else if (a == NULL) //a == NULL就打印
{
printf("没有找到\n");
}
}
看看结果
欸?什么情况?ccb不是有吗?为什么找不到?
现在用语言来解释下
截出要扫描的字符串ccb那段地方来进行说明
“cccbbb”
现在把自己想象成循环设置 i 为↑; i < 6 ; i++,我现在要搜索ccb设 j 为! j < 3
现在指向第一个字符
c c c b b b
↑
诶,真幸运第一个就看到c了
那 j 就开始和 i 一起++
c c c b b b
↑
c c b
!
往后
c c c b b b
↑
c c b
!
往后
c c c b b b
↑
c c b
!
诶,不一样了 j 遗憾置为0
但是 i 呢? i 兄弟没减1,他现在停在了c c c 最后一个c 那里
现在i++
c c c b b b
↑
这样在这段字符串中就找不到ccb了
但是再看看你们可能看出来了c应该-2才能到达c c b 的第一个c啊,是不是说错了呢?
我们再看看代码
const char* sstrstr(const char* str, const char* str2)
{
int i = 0;
int j = 0; //用于循环要查找的数组
while(*(str + i) != '\0')
{
if (*(str + i) == *(str2 + j)) //进行判断 如果开始等于了进入下面的循环
{
while (1) //这里不会死循环的,下面有终止条件,不用担心
{
if (*(str + i) == *(str2 + j)) //进行判断如果还等于,就继续循环
{
i++;
j++;
if (*(str2 + j) == '\0') //判断如果 要查找的字符串 循环完了就返回它第一个字符出现的地址
{
return (str + i - j); //可能还有人不懂,这里再进行说明函数只要一遇到return就会直接停止,整个函数停止
}
}
else if(j == 1) //如果j只加了一次就只需j置为0就行,为什么呢?下面用文字说明,代码里不说那么多
{
j = 0;
break;
}
else //其他情况就i - 1,同时j也要置为0;
{
i = i - 1;
j = 0;
break;
}
}
}
else //什么都没找到i++继续找就完事了
{
i++;
}
}
return NULL; //如果没找到就返回空指针
}
由上到下看下第一个i++的位置和第第二个i++的位置第一个i++在第二层循环的if判断里
第二个是在第一层循环的if判断里,而第二层循环也在第一层循环的判断里
而if只会执行其中一个,再看看第二层循环里的 if 也是只会执行其中一个
因为最后字母一个不相等,j 不等于1就执行最后一个
此时 i 没有再++了所以直接减去 1 就行
为什么j==1时i不用减去1呢?
同样把自己当成循环设置 i 为↑; i < 6 ; i++,我现在要搜索ccb设 j 为! j < 3
设置要扫描的字符串为ccbbc
要搜索cbb
开始跑
c c b b c
↑
诶运气真好第一个就是
开始跑j
c c b b c
↑
c b b
!
走
c c b b c
↑
c b b
!
不一样了,i 减去1,j 置0;
i 减去 1 后退回
c c b b c
↑
诶,已经出问题了
又跑回了第一位
这样就会造成死循环了
至于指针为什么是常量呢?看看代码写得这么长,如果中途有点什么操作不小心把指针的值改了就不好了.
好了模拟strstr就讲到这,怎么样简单吧?
如果还有什么地方不懂,或者代码中还有什么bug,欢迎提出,问题的话如果在我力所能及的范围我会回答的。
感谢大家的阅读
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183463.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...