前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解字符串函数(strstr、strtok、strerror)(二)

深入理解字符串函数(strstr、strtok、strerror)(二)

作者头像
走在努力路上的自己
发布2024-01-26 16:39:13
1860
发布2024-01-26 16:39:13
举报
文章被收录于专栏:走在努力路上的自己

strstr 的使用和模拟实现​

作用:返回字符串在另外一个字符串中第一次出现的位置,即查找子串

  • 在字符串str1中查找是否存在与str2相等的子串
  • 如果存在,则返回一个地址(返回字符串str2在字符串str1中第⼀次出现的位置)
  • 如果不存在,则返回空指针

char * strstr ( const char * str1, const char * str2); Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1. (函数返回字符串str2在字符串str1中第一次出现的位置)。​ The matching process does not include the terminating null-characters, but it stops there.(字符串的比较匹配不包含 \0 字符,以 \0 作为结束标志)。

const char* str1:被查找目标字符串

const char* str2:要查找的对象字符串

简单的使用:
代码语言:javascript
复制
int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "def";
	char* ret = strstr(arr1, arr2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else {
		printf("找不到\n");
	}
	return 0;
}

<注:只要子串存在,strstr函数不仅打印出子串a2的内容,还会打印出子串arr2在arr1所处位置以后的所有字符 >

复杂情况下的使用
代码语言:javascript
复制
int main()
{
	char arr3[] = "abbbcdef";
	char arr4[] = "bbc";
	char* ret = strstr(arr3, arr4);
	if (ret == NULL) {
		printf("此字符串不存在,查找失败!\n");
	}
	else {
		printf("%s\n", ret);//bbcdef
	}
}

通过输出结果可知,ret的字符串为:"bbcdef"

当函数首先用指针str1指向a3的首字符时,

字符a不等于指针str2指向arr4字符串的字符b,str1会指向下一个字符进行寻找,

str1指向了字符b,发现与str2指向的相等,然后两个指针继续进行一次对比,又相等后,发现str1后的一个字符为b,而str2此时为c,不相等,再指向下一个字符进行比较

在str1再指向下一个字符时,对比成功,在这str1和str2数次对比后,str2已经指向了字符'\0'(),此时终止比较,返回值为str1中bbc后的所有内容。

模拟实现strstr函数
用暴力求解的方式:
  • const char* cur = str1; 初始化一个指针cur,指向源字符串str1的开始。
  • const char* s1 = NULL;const char* s2 = NULL; 初始化两个指针s1和s2,分别用于遍历源字符串和目标字符串。
  • assert(str1 && str2);//保证指针有效 通过assert确保传入的两个指针都是有效的。
  • if (*str2 == '\0') return (char*)str1; 如果目标字符串是空字符串,直接返回源字符串的地址。
  • while (*cur)//保证字符串cur即str1不为空 使用while循环遍历源字符串,直到遇到空字符'\0'。
  • s1 = cur; s2 = str2; 初始化s1和s2指针,分别指向当前遍历到的源字符串位置和目标字符串位置,替代源字符串,保证s1和s2的内容不变。
  • while (*s1 && *s2 && *s1 == *s2)//确保*s1和*s2不是'\0' 使用while循环遍历源字符串和目标字符串,直到两个指针都指向空字符,或者两个当前字符不相等。
  • if (*s2 == '\0') return (char*)cur; 如果目标字符串遍历完,返回当前源字符串的位置。
  • cur++; s2++; 移动指针cur和s2,指向下一个字符。
  • if (ret != NULL) 通过检查返回值判断是否找到了匹配的子字符串。
  • printf("%s\n", ret); 如果找到了匹配的子字符串,打印该子字符串。
代码语言:javascript
复制
//暴力求解的方式
char* my_strstr(const char* str1,const char* str2)
{
	const char* cur = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;

	assert(str1 && str2);//保证指针有效
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*cur)//保证字符串cur即str1不为空
	{
		s1 = cur;
		s2 = str2;
		//确保*s1和*s2不是\0
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "bcd";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else {
		printf("找不到\n");
	}
	return 0;
}

还有一种是KMP求解法,以后会更新,望多多包涵

strtok的使用

strtok作用:字符串切割 char * strtok ( char * str, const char * sep); • sep参数指向一个字符串,定义了用作分隔符的字符集合​ • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。内部可能有静态变量) • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。 • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 • 如果字符串中不存在更多的标记,则返回 NULL 指针。

代码语言:javascript
复制
int main()
{
	char arr1[] = "zhangsan@163.com";
	char arr2[30] = { 0 };//zhangsan\0163\0com
	strcpy(arr2, arr1);
	const char* p = "@.";
	char* s = NULL;
	//    初始化部分只执行一次
	for (s = strtok(arr2, p); s != NULL;s = strtok(NULL,p))
	{
		printf("%s\n", s);
	}

	return 0;
}
  • char arr1[] = "zhangsan@163.com";定义了一个字符数组 arr1,并将它初始化为字符串 "zhangsan@163.com"。
  • char arr2[30] = { 0 };定义了一个字符数组 arr2,长度为30,并将每个字符初始化为0。这里的0是空字符,意味着字符串的结束。
  • strcpy(arr2, arr1);使用 strcpy 函数将 arr1 的内容复制到 arr2。这样,arr2 就包含了与 arr1 相同的字符串。
  • const char* p = "@.";定义了一个常量字符指针 p,并将其指向字符串 "@."。这里的 "@." 是一个分隔符,它告诉 strtok 函数在哪里分割字符串。
  • char* s = NULL;定义了一个字符指针 s,并初始化为 NULL。
  • for (s = strtok(arr2, p); s != NULL; s = strtok(NULL,p));这是一个循环,它使用 strtok 函数来分割 arr2。首次调用时,strtok 会使用 p 中指定的分隔符来分割 arr2。之后每次调用,strtok 会继续在上一次分割的位置之后寻找下一个分隔符。当找不到更多分隔符时,strtok 返回 NULL,循环结束。

strerror 函数的使用​

char * strerror ( int errnum ); strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。​ 在不同的系统和C语言标准库的实现中都规定了一些错误码,一般是放在 errno.h 这个头文件中说明的,C语言程序启动的时候就会使用一个全面的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会讲对应的错误码,存放在errno中,而一个错误码的数字是整数很难理解是什么意思,所以每一个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

这是打印0~9错误码的代码:

代码语言:javascript
复制
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d:%s\n", i, strerror(i));
	}
	return 0;
}

今天就先到这了!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • strstr 的使用和模拟实现​
    • 简单的使用:
      • 复杂情况下的使用
        • 模拟实现strstr函数
          • 用暴力求解的方式:
      • strtok的使用
      • strerror 函数的使用​
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档