模拟实现strstr()函数

strstr()函数

含义为:在一个字符串中查找另外一个字符串

在msdn中,这样解释:

该函数的定义为

char* strstr(const char* str1, const char* str2);

函数输出的是地址,也就是str2在str1中第一次被找到时的首元素的地址,如果找不到则返回空指针(null)

思路分析:

传入两个指针str1和str2后,想要在str1中找到str2,就要在str1中遍历每个元素,首先在str1中找到与str2中首元素相同的地址,在该地址的基础上,往后一一配对,如果发现匹配不上,则说明从这个地址往后找不到str2,该地址往后跳一格再次判断上述操作。但是,函数最后是要输出首次找到时的地址,所以我们不能直接把str1,str2输出,还需要指针来记录这个地址。

因此,我们发现,想要完成这些操作,需要额外添加三个指针,第一个最先指向str1首元素的地址,用处为每次匹配时指向匹配的起始位置,第二个指针则是进行某一匹配轮次时str1的首元素地址(与第一个指针相同),第三个指针则是进行匹配时str2的首元素地址。第二个指针和第三个指针的用途显而易见,判断是否匹配后,是则指针+1,不是则跳出。

while (*s1 == *s2)
{
    s1++;
    s2++;
}

我们分析一下四种情况:

1.

char str1[] = "abcdefg";
char str2[] = "bcd";

最常见的一种情况,只需正常遍历到b后,匹配到b及以后的str2的所有元素,这里停止的办法是当str2到' \0 ',由于' \0 ' 也与 ' e '不相同,所以跳出循环。

2.

char str1[] = "abccdefg";
char str2[] = "cde";

这里当遍历到第一个c的时候,往后匹配发现并不是str2,此时就要使用第一个指针,将其+1去和第二个c匹配

3.

char str1[] = "abc";
char str2[] = "abc";

这里当两个字符串完全相同时,匹配后同时到达' \0 ' ,如果还继续往后匹配就会越界访问,导致错误,此时就需要增加限制条件:如果第三个指针能到达' \0 ',则说明str1已经找到了str2,不需要再继续匹配,可以返回该匹配轮次时的第一个指针

4.

char str1[] = "abc";
char str2[] = "bcd";

这里当匹配完' b ' 和 ' c ' 后,进行' \0 ' 与 ' d '的比较,这显然是无意义的,所以增加限制 第二个指针指向的内容不能为' \0 '

综上所述,根据需求,我们可以写出如下代码:

#include <stdio.h>
char* my_strstr(const char* str1, const char* str2)
{
    const char* s1 = NULL;
    const char* s2 = NULL;
    const char* current_p = str1;
    if (*str2 == '\0')
        return (char*)str1;
    while (*current_p)
    {
        s1 = current_p;
        s2 = str2;
        while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
        {
            s1++;
            s2++;
        }
        if (*s2 == '\0')
            return (char*)current_p;
        current_p++;
    }
    return NULL;
}
int main()
{
    char str1[] = "abbcdef";
    char str2[] = "bc";
    char* ret = my_strstr(str1, str2);
    printf("%s", ret);
    return 0;
}    

值得注意的是,当str2为空时,匹配没意义,单独拿出来判断并返回空指针

所有返回的空指针都需要进行强制类型转换

以上便是模拟strstr()函数的方法之一,这种方法算是暴力求解了

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值