C语言进阶(九) - 字符与字符串函数 - 4 - strstr()函数、strtok()函数、strerror()函数

前言

主要介绍字符串相关函数中的strstr()函数strtok()函数strerror()函数

1. strstr()函数

1.1 strstr()函数介绍

E4MO4@{_4ABG1R3IKYOVCYU.png
点击转到cpluscplus.com官网 - strstr
所需头文件为<string.h>

功能:在前一个字符串str1中找后一个字符串是否出现在前一个字符串中。就是查找子字符串
返回值:返回str1中第一个出现的str2的指针如果str2不是str1的一部分就返回空指针。

例子:

#include <stdio.h>
#include <string.h>

int main() {
	char str1[] = "123456789@qq.com";
	char str2[] = "12345";
	char* p = strstr(str1, str2);
	if (p) {
		puts(p);
	}
	else {
		printf("没找到\n");
	}
	return 0;
}

运行结果:
.png

1.2 模拟实现strstr()函数 - 暴力求解法

本质是比较字符串,在字符相同的情况下,依次比较下一对字符直到遇到str2中的'\0'就说明找到了。或者遇到str1'\0'说明没找到。或者下一对字符不相等,再重新开始比较:str1在上一次跳过字符的基础上再跳过一个字符,str2跳回起始字符。
在比较中需要记录待比较字符的位置,s1指向str1即主串,s2指向str2即子串;比较失败时s1需要回跳到本次比较起始位置的下一个字符地址。s2回跳到str1起始字符地址。开始下一次比较。

//模拟实现strstr
//一般算法
#include <stdio.h>
#include <string.h>
#include <assert.h>

char* my_strstr(const char* str1, const char* str2) {
	//断言
	assert(str1 && str2);
	//s1指向待查找的字符串str1
	const char* s1 = str1;
	//s2指向字符串str2
	const char* s2 = str2;
	//p指向字符串str1,每次s1与s2移动时保持不变,以便当前查找失败时s1能够找到下次查找的位置
	const char* p = str1;

	while (*p) {
		//每次查找开始时,s1指向被p更新
		s1 = p;
		//s1与s2都没有指向字符串末尾,且二者所指向字符相等
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
			s1++;
			s2++;
		}
		//是否到达str2字符串的末尾,若到达就返回本次查找的起始地址
		if (*s2 == '\0') {
			return (char*)p;
		}
		//本次查找未找到
		p++;
	}
	return NULL;
}
int main() {
	char str1[] = "aasfb";
	char str2[] = "b";
	char* p = my_strstr(str1, str2);
	if (p) {
		printf("找到了: %s", p);
	}
	else {
		printf("%s不存在\n", str2);
	}

	return 0;
}

2. strtok()函数

2.2 strtok()函数介绍

char * strtok ( char * str, const char * delimiters );
所需头文件为<string.h>

  • 这个函数可以把一个含有分隔符的字符串通过分隔符的集合分成多个子字符串。
  • delimiters参数是个字符串,定义了用作分隔符的字符集合。
  • 参数str指向一个字符串,它包含了0个或多个由delimiters字符串中一个或多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记(子字符串),并将其用'\0'结尾,返回一个指向这个标记的指针。
  • strtok函数会改变(破坏)被操作的字符串,所以使用strtok函数切割的字符串一般是副本并且可以被修改。
  • strtok函数的第一个参数不是NULL时,函数将找到传入字符串str中的第一个标记(子字符串),strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数是NULL时(大概率说明这不是第一次调用,否则返回空指针NULL),函数将在同一个字符串中被保存的位置开始,查找下一个标记(子字符串)。
  • 如果字符串不存在更多的标记,返回空指针NULL

2.3 例子

#include <stdio.h>
#include <string.h>

int main() {
	char str1[] = "123456789@qq.com";
	char str2[20] = { 0 };
	strcpy(str2, str1);
	char str3[] = { "@." };

	for (char* p = strtok(str2, str3); p != NULL; p = strtok(NULL, str3)) {
		printf("%s\n", p);
	}
	return 0;
}

运行结果:
2$3U45FHNI_H6(3MA$1_V@P.png

#include <stdio.h>
#include <string.h>

int main() {
	char str1[] = "123456789@qq.com";
	char str2[20] = { 0 };
	strcpy(str2, str1);
	char str3[] = { "@." };

	printf("%s\n", strtok(str2, str3));
	printf("%s\n", strtok(NULL, str3));
	strcpy(str2, str1);
	printf("%s\n", strtok(str2, str3));
	printf("%s\n", strtok(NULL, str3));
	printf("%s\n", strtok(NULL, str3));

	return 0;
}

运行结果:
image.png


3. strerror()函数

3.1 strerror()函数介绍

char* strerror (int errnum);
1.png
点击转到cplusplus.com官网 - strerror
所需头文件为<string.h>

  • 这个函数接收一个整型的错误码errnum返回一个字符指针,指向了包含与错误码有关的错误信息的相应的字符串。
  • 返回的指针指向一个静态分配的字符串,该字符串不能被程序修改。对这个函数的进一步调用可能会覆盖它的内容(不需要特定的库实现来避免数据竞争)。
  • C语言的库函数在执行失败的时候会生成错误码。这个错误码由变量errno记录,可以被心得错误码覆盖。调用strerror函数时就可以传入errno
  • 使用errno调用库函数的头文件是<errno.h>

3.2 例子

#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main (){
  FILE * pFile;
  //已知记事本hello.text不存在
  pFile = fopen ("hello,txt","r");
  if (pFile == NULL)
    printf ("Error opening file unexist.ent: %s\n",strerror(errno));

  return 0; 
}

运行结果:
.png


END

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

re怠惰的未禾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值