1.分情况讨论
strstr 函数的功能:
用来在一个字符串内搜索一个子串的首次出现位置的函数。如果找到了子串,strstr会返回子串首次出现的地址;如果没有找到,则返回NULL。
匹配字符串时会出现 2 种情况。
case 1:
char arr1[]="abcedf"; char arr2[]="bcd";case 2:
char arr1[] = "abbbcd"; char arr2[] = "bbc";case 1 是简单的子字符串寻找,一次就能匹配到;case 2 是比较复杂的子字符串寻找,需要多次匹配。
2.画图说明
接下来画图说明 case 2:
在str1中匹配子字符串的每一个字符,s1 和 s2 都指向字符串的起始位置,让 s1 s2 指向的字符进行匹配,如果不匹配, 移动 s1到下一个字符。
发现 str1 和 str2 的字符是一样的,就有字符串匹配成功的可能,当s1 s2 都走到:
画图中的位置时,子字符串没有和 str1 的字符串匹配成功,需要用第3个变量 p来记录str1中和子字符串开始匹配字符的下一个字符的位置( 第 2 个 b ),并作为s1重新匹配的起点,再次和回到起始位置的 str2(子字符串) 进行重新匹配。如果匹配成功就返回第二个b的地址。为了记录匹配失败的字符的后一个字符的位置,就需要 变量 p 在开始的时候也指向 str1。
于是用 变量 p 在第一个字符开始记录,没匹配成功,让 p 记录在当前位置(匹配失败字符)的下一个字符的位置,给 s1 赋值 p, s2也回到起始位置再次匹配 ,直到 p已经到了 \0。如果找到了,就提前返回会 p, 如果到了 \0 还没找到,就返回 NULL。
3.代码实现
char* MyStrstr(const char* str1, const char* str2) { assert(str1 && 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++; } //要么匹配失败停止循环,要么字符都匹配*s2==0,说明匹配成功返回地址 if (*s2 == '\0') { return (char*) p; } p++; } return NULL; } int main() { char arr1[] = "abbbcd"; char arr2[] = "bbc"; char * ret=MyStrstr(arr1, arr2); if (ret == NULL) { printf("子串不存在\n"); } else { printf("%s\n", ret); } return 0; }