详解strstr函数:查找子字符串函数及其模拟实现

简介: 详解strstr函数:查找子字符串函数及其模拟实现

对于strstr查找子字符串,笔者如果不是对C语言学习的更加深入,可能还是不知道有这个函数!!!之前,我们在一个字符串里面查找另外一共字符串都是用指针来遍历整个字符串来查找!!!现在相信各位老铁通过对此博客的学习,等到心有感悟的时候,便能使用该strstr函数来查找了!简单了不少!


对于 strstr查找子字符串函数的语法有:


0a2653c851af460fa595bd959398a8f1.png


//在C++中:const char * strstr ( const char * str1, const char * str2 );
//在C中  :      char * strstr (       char * str1, const char * str2 );

需要注意的是,返回值的类型为:char*类型的指针!!


显而易见的就是:在字符串str1里面查找是否含有字符串str2!!


比如:在字符串str1[]="abcdefabcdefabcdef"里面查找是否含有字符串arr2[]="fab"!!!


如果存在,返回的是子串第一次所在的起始位置!


如果不存在,返回的是:NULL(空指针)


但是在str1[]="abcdefabcdefabcdef"含有两次arr2[]="fab",只返回第一次出现的位置!!


2d65d23f6d4748949b924e4057485923.png


请看代码:


#include <stdio.h>
#include <string.h>
int main()
{
  char arr1[] = "abcdefabcdefabcdef";
  char arr2[] = "fab";
  char* p = strstr(arr1, arr2);
  if (p == NULL)
  {
  printf("不存在\n");
  }
  else
  {
  printf("%s\n", p);
  }
  return 0;
}


因为 strstr函数的返回值类型为char*类型的指针!!所以需要用char*类型的指针来接收!所以定义了char *p!!当返回值为NULL的时候,打印不存在,否则,打印出来:将p当作起始地址的字符串!!


代码的运行结果为:


6de278e6d6694ce5bb08e7e842b7e74b.png


但是对于返回的是否是第一次出现的位置??想必各位老铁可能心存疑惑!!但是,经过上面的代码的运行结果,想必大家也能解决掉该疑惑了吧!!!


下面进入最精彩的部分!strstr函数的模拟实现!!也到了压轴的部分了!请睁大眼睛看仔细。


情况1.


12c3b7f3f8814309a195c64f051d4445.png


s1与s2这两个指针不相等,s1++;,当s1与s2这两个指针相等的时候,p此时记录的是s1处的位置,s1++;s2++;各往后走一步,一直到s2走完!!


情况2:

34e8d716411043c08c7ffba9fbba23de.png


当s1与s2不相等时,此时p记录的为b的位置,则p从c的位置开始往后找!!


情况3:


92ba0822ed0b46e1ae72df8a17d3a45b.png


第一趟走的时候,发现不相等,对于str2,指针重新回到原处,str1++;继续往后找!!


经过上面的简单分析:我们可以得出下面的代码:


#include <stdio.h>
#include <string.h>
char* my_strstr(const char* str1, const char* str2)
{
  const char* s1 = str1;
  const char* s2 = str2;
  const char* p = str1;
  while (*p)
  {
  s1 = p;
  s2 = str2;
  while (*s1 != '\0' && *s2 != '\0' && (*s1 == *s2))
  {
    s1++;
    s2++;
  }
  if (*s2 == '\0')
  {
    return p;
  }
  p++;
  }
  return NULL;  //找不到子串
}
int main()
{
  char arr1[] = "abcdefabcdef";
  char arr2[] = "cde";
  char* p = my_strstr(arr1, arr2);
  if (p == NULL)
  {
  printf("不存在\n");
  }
  else
  {
  printf("%s\n", p);
  }
  return 0;
}


解析:


1.对于第一个while循环里面:while(*p) 中的*p如果不等于’\0‘就进入!


2.对于:s1 = p; 认为在p处位置可能匹配成功,讲p赋值给s1,让s1遍历往后走,看看能不能匹配成功!


3.对于:s2 = str2; 将s2回到起始位置!


4.对于p++; 当s1与 s2不相等的时候,p++,使得p往后走,跳过刚刚匹配的位置,重新进入while循环,再次进行判断!!


用上述代码在:abbbcdef里面查找bbc的主要过程:


d79b274929334152a6d38be91e2d1be3.png


解析为:


将str1与 str2分别指向两个字符串的起始地址!并通过    const char* s1 = str1;    const char* s2 = str2; 也让s1 和s2分别指向两个字符串的起始位置!!指针p也在开始的时候指向str1的位置,让s1 与s2指向的两个位置比较一下,发现不相等,让p往后走(p++),再通过s1=p,将p的位置赋值给s1,s2回到起始位置,将s1 与s2进行比较,相等的话,s1++; s2++; 都往后走,判断又相等,再往后走,发现s1指向b,s2指向c,不相等,则p++;使p往后再走一步,再通过s1=p将s1回到p指向的位置处,通过s2=str2,再将s2回到初始位置,重新进行比较,当两个字符串有一个遇见'\0'时,就会停下来!!


上面内容就是主要的解析!!请各位老铁仔细品味!!


最后,此处代码的运行结果为:

dfc80ca9d8004e6c9ddc00e8448ffc6a.png

相关文章
|
8月前
[字符串和内存函数]strcmp字符串函数的详解和模拟
[字符串和内存函数]strcmp字符串函数的详解和模拟
64 1
|
8月前
|
C语言
[字符串和内存函数]strcat字符串函数的详解和模拟
[字符串和内存函数]strcat字符串函数的详解和模拟
56 0
|
2月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
143 4
|
8月前
|
存储 C语言
学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))
学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))
83 0
下列给定程序中函数fun的功能是:统计substr所指的子符串在str所指的字符串中出现的次数。
下列给定程序中函数fun的功能是:统计substr所指的子符串在str所指的字符串中出现的次数。
101 0
模拟实现库函数strstr--查找子字符串
模拟实现库函数strstr--查找子字符串
|
C语言 C++
转换符说明使用方法(在printf函数中)
一些常见的转换说明及打印结果: printf()的转换说明修饰符 printf()函数打印数据指令时要与代打印数据的类型相匹配才行。 如%d %c %ld......这些符号叫做转换说明。代表着数据转化成显示的形式。 一些常见的转换说明及打印结果: 转换说明 输出 %d 有符号十进制整数 %c 单个字符 %A 浮点数,十六进制数和p计数法(c99/c11) %a 浮点数,十六进制数和p计数法(c99/c11) %f 浮点数,十进制计数法 %e 浮点数,e计数法 %E 浮点数,e计数法 %i 有符号十进制整数 %o 无符号八进制整数 %p 指针(地址) %s 字符串 %u 无符号十进制整数
175 1
实现一个函数,使用指针连接两个字符串。函数输入:两个源字符串的指针,目的字符串的指针。
实现一个函数,使用指针连接两个字符串。函数输入:两个源字符串的指针,目的字符串的指针。