内容重点:
重点介绍处理字符和字符串的库函数的使用和注意事项
下面是将要介绍的几个函数:
- 求字符串长度 strlen
- 长度不受限制的字符串函数 strcpy strcat strcmp
- 长度受限制的字符串函数介绍 strncpy strncat strncmp
- 字符串查找 strstr(本节)strtok
- 错误信息报告 strerror
- 字符操作
- 内存操作函数 memcpy memmove memset memcmp
本节内容:
- strstr
- strchr
- strrchr
- 模拟实现strstr
strstr
char * strstr ( const char *str1, const char * str2);
译文:
定位子字符串
返回指向str1中第一个出现的str2的指针,如果str2不是str1的一部分,则返回null指针。
匹配过程不包括终止的null字符,但仅限于此。
返回值
译文:
指向在str2中指定的整个字符序列的str1中第一个出现的指针,如果该序列不在str1中,则为空指针。
简单来说:在str1中找str2出现的位置,返回str2的字符串在str1字符串第一次出现的位置。如果找不到返回空指针。
1.使用示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdebcdef";
char arr2[] = "bcd";
char* p = strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到");
}
else
{
printf("%s\n", p);
}
return 0;
}
输出结果:
strchr
const char * strchr ( const char * str, int character );
或者
char * strchr ( const char * str, int character );
译文:
查找字符串中第一个出现的字符
返回一个指针,指向C字符串str中第一个出现的字符。
终止的null字符被认为是C字符串的一部分。因此,也可以定位它,以便检索指向字符串末尾的指针。
用法:与strstr 函数比较类似的函数,用来找出一个字符在一个字符串中第一次出现的位置
使用示例
例1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdebcdef";
char str = 'e';
char* p = strchr(arr1, str);
if (p == NULL)
{
printf("找不到");
}
else
{
printf("%s\n", p);
}
return 0;
}
输出结果:
strrchr
const char * strrchr ( const char * str, int character );
或者
char * strrchr ( char * str, int character );
译文:
查找字符串中最后一个出现的字符
返回一个指针,指向C字符串str中最后一个出现的字符。
终止的null字符被认为是C字符串的一部分。因此,也可以定位它来检索指向字符串末尾的指针。
用法:用来找出一个字符在一个字符串最后出现的位置
使用示例
例题1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdebcdef";
char str = 'e';
char* p = strrchr(arr1, str);
if (p == NULL)
{
printf("找不到");
}
else
{
printf("%s\n", p);
}
return 0;
}
输出结果:
模拟实现strstr
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
char* s1 = NULL;
char* s2 = NULL;
char* cp = (char*)str1;//cp作为标记
while (*cp)
{
s1 = cp;
s2 = (char*)str2;
while (*s1 && *s2 && *s1 == *s2)//s1空为没有匹配项,s2为空则匹配成功
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;//为了判断是否找到了,找到了直接跳出
}
cp++;
}
return NULL;//没有找到返回空指针
}
int main()
{
char arr1[] = "abbbcdef";
char arr2[] = "bbc";
char* p = my_strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到\n");
}
else
{
printf("%s\n", p);
}
return 0;
}
输出结果:
解释:
在对该代码进行解释之前,我们先用其他例子来进行说明,便于代码的理解。
示例1 :当arr1[]=“abcdebcdf”,arr2[]=“bcd”时
a与b不匹配,指向arr1开头的指针需要移动到下一个字符b,而arr2的指针不需要移动。之后继续操作,b与b相等,c与c相等,d与d相等,因此arr1和arr2匹配上了,就此结束。
首先我们必须先需要对两个指针进行比较,即先创建*str1和*str2两个指针并且都分别指向两个数组的开头位置。分别对两个指针指向内容来进行匹配即可
但是如果出现
示例2:当arr1[]=“abbbcdeff”,arr2[]=“bbc”时
顺着刚刚的思路,a与b不匹配,指向arr1开头的指针需要移动到下一个字符b,而arr2的指针不需要移动。之后继续操作,arr1的第一个b与arr2的b匹配上了,arr1的第二个b与第二个b匹配上了,arr1的第三个b与arr2c没有匹配上。但是我们可以看到arr2的bbc是从arr1的第二个b才开始匹配上的。
因此我们需要一个指针记住刚刚的位置,使得s1能够从开始匹配成功时(两个字符相等)能够重新开始与s2的指向内容重新匹配(s1=cp,之后开始匹配),因此引入cp。那么s2也需要重新返回开头重新匹配(s2=str2)。每当两个字符完全不相等(完全不可能匹配上,这里也就是两个数组第一个字符(arr1是a,arr2是b)不匹配的情况。)或者arr2匹配过一轮时,直接让cp++,让s1返回到cp标记下一个位置。
我们看这道题,每当开始匹配成功时,这里也就是第一个b开始匹配上,直到s1为b,s2为c时,此时匹配失败,此时我们需要让s1的位置重新回到开始匹配上的下一个位置(也就是第二个b)那么在之前需要cp++,然后s1=cp;同时让s2回到刚刚的位置,重新开始匹配(s2=str2)
大致我们搞清楚了,因此我们需要先循环匹配while(s1和s2的内容是否相等),同时满足s1,s2的内容不为'\0',s1为'\0'则表面s2没有满足匹配的;s2为'\0',则表面s1与s2已经匹配成功;但是我们需要注意的是整个while的条件,当*cp的指向还有内容时,我们需要继续循环。
当然了一些小细节还是需要多思考一下的,这个函数实现非常的巧妙。