实现库函数strstr()

170 阅读1分钟

1)my_strstr()的实现:
#include <stdio.h>
#include <string.h>

char* my_strstr(const char* p1, const char* p2);

int main()
{
	printf("输入:\n");
	char a[20] = { '\0' };
	gets_s(a);

	char b[20] = { '\0' };
	gets_s(b);

	printf("\n输出:\n");
	printf("%s(my_strstr())\n", my_strstr(a, b));
	printf("%s(strstr())\n", strstr(a, b));
	return 0;
}

char* my_strstr(const char* p1, const char* p2)
{
	char* s1 = (char*)p1;
	char* s2 = (char*)p2;
	char* po = (char*)p1;

	while (*s1 != '\0')
	{
		po = s1;
		s2 = (char*)p2;
		while (*po == *s2 && *s2 != '\0')
		{
			++po;
			++s2;
		}
		if (*s2 == '\0')
		{
			return s1;
		}
		++s1;
	}
	return NULL;
}

2)运行结果展示:
输入:
AABB
AB

输出:
ABB (my_strstr)
ABB (strstr)
输入:
AABB
AV

输出:
(null) (my_strstr)
(null) (strstr)

3)对于po指针的注释:
/*
指针po是为指针s1探路的,相当于s1替身。

每当发现(p1所指向的字符  ==  p2所指向的字符串的首字符)时,
po就代替s1开始向后走,此时有两种可能的结果:
1)po走到某位置,发现与s2所指字符不相等了,此时s1++,po返回s1位置。
2)po走完与s2匹配的全过程。

设置po指针是考虑到有这种情况:
字符串A:"AAB"
字符串B:"AB"

试想,若无po指针,s1指针指向第一个'A'时,匹配开始,s1自己向后走,
当匹配到第二个'A',匹配失败,这时难道就认为没有不存在子串吗?
当然不能,因为若从第二个'A'开始匹配就显然可以找到子串"AB"。
但这时s1已经不可能找回去往第二个'A'的路了(因为实际情况中我们不知道匹配到哪里会出错)。
*/

4)strstr()的源码:
char * __cdecl strstr(const char *str1, const char *str2)
{
    char *cp = (char *)str1;
    char *s1, *s2;

    if (!*str2)
        return((char *)str1);

    while (*cp)
    {
        s1 = cp;
        s2 = (char *)str2;

        while (*s2 && !(*s1 - *s2))
            s1++, s2++;

        if (!*s2)
            return(cp);

        cp++;
    }
    
    return NULL;
}