C语言进阶之字符串查找库函数详解

strstr

查找strstr的文档,可知它的原型为:

char *strstr( const char *string, const char *strCharSet );

它的返回值,根据文档是这样的: 

Return Value

Each of these functions returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. If strCharSet points to a string of zero length, the function returns string.

可知会返回一个指针,指向目标字符串在strCharSet中第一次出现的位置。如果没有,就返回一个空指针。

简单地说,就是查找子字符串。

由于返回值是指针,那么接收返回值就要用指针类型来接收。

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abbbcdbbcef";
	char arr2[] = "bbc";
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

输出结果如下:

如果我把arr2改成bbcq,那么在arr1中找不到arr2,就会返回空指针:

现在来模拟实现strstr。

分为两种情况。

情况1:

这种情况较为简单,arr1首先指向a,arr2指向b,a和b不相等,那么arr1指向下一个字符,此时arr2仍指向b,此时arr1和arr2指向的字符相等,那么arr2指向下一个字符,arr1也指向下一个字符,发现arr1和arr2指向的字符相等,那么arr2指向下一个字符,这时指向了\0,就停止了查找。

情况2:

arr1最开始指向a,arr2最开始指向b。

arr1和arr2所指向的字符不相等,那么arr1就指向下一个字符,arr2仍指向第一个b,此时arr1和arr2指向的字符相等,那么arr2指向下一个字符,arr1也指向下一个字符,发现arr1和arr2指向的字符相等,那么arr1和arr2继续指向下一个字符,此时arr1和arr2分别所指向的字符不相等,而此时arr2也不能向前指了,那么就停止了查找。

显而易见,这是有问题的!问题就在于第一个字符串里明明有第二个字符串的存在,却没有查找到。

正确的做法是,arr1指向出现的第二个b,arr2指向第一个字符,然后重新查找。

那么此时就需要有一些临时变量,不要用arr1和arr2亲自查找。

可以这样来实现模拟strstr:

#include <string.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	if (*str2 == '\0')//用于判断srr2是不是空字符串
	{
		return (char*)str1;
	}
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cp = str1;
	while (*cp)//当*cp为0时终止循环
	{
		s1 = cp;
		s2 = str2;//内循环每次开始前s2都指向要查找的字符串首元素,s1指向被查找的字符串里下一个字符
		while (*s1 !='\0' && *s2!='\0' && *s1 == *s2)
		{
			s1++;
			s2++;//只要字符串不结束并且指向的字符相等就循环
		}
		if (*s2 == '\0')//如果条件成立,说明找到了子字符串
		{
			return (char*)cp;
		}
		cp++;
	}
	return NULL;
}

strtok

这个函数不管是使用还是原理,都相当独特。其原型如下:

char *strtok( char *strToken, const char *strDelimit );

sep参数是个字符串,定义了用作分隔符的字符集合。

第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记。

strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被其操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。

strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。

如果字符串中不存在更多的标记,则返回 NULL 指针。

字符串superverybest@outlooks.net是由@和.切开的,@和.其实就是分隔符。那么要将superverybest、outlooks、net分隔开,可以这样:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "superverybest@outlooks.net";
	char* p = "@.";
	char buf[50] = { 0 };
	strcpy(buf, arr);
	char* ret = NULL;
	for (ret = strtok(buf, p); ret != NULL; ret=strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

输出结果为:

总结

作者:工业废气 原文地址:https://blog.csdn.net/m0_60464690/article/details/128703024

%s 个评论

要回复文章请先登录注册