• C语言之字符串函数二


    strstr:查找字符串

    strstr(p1(字符串),p2),在p1中寻找p2(子串)

    举例:

    #include
    #include
    int main()
    {
    	const char* p1 = "abcdef";
    	const char* p2 = "def";
    	const char*ret=strstr(p1, p2);//在p1中寻找p2
    	//NUll/NUL(空指针---‘\0’)
    	if (ret == NULL)//如果p1中不包含p2,则ret指向的为空指针
    	{
    		printf("子串不存在");
    	}
    	else//如果p1中包含p2,则我们直接返回指针的值
    	{
    		printf("%s\n", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    输出结果:

    def
    
    • 1

    如果将p2修改为如下所示:

    const char* p2 = "defhi";
    
    • 1

    输出结果为:

    子串不存在
    
    • 1

    那么strstr到底返回的是包含子串的字符串还是子串呢?

    现在我们将p1修改为如下所示:

    const char* p1 = "abdefcdefbsdicwid";
    
    • 1
    defcdefbsdicwid
    
    • 1

    通过输出结果,我们不难发现strstr返回的值并不是子串,而是在字符串中第一次出现子串后的所有内容。

    模拟实现strstr的原理:

    #include
    #include
    #include
    char*my_strstr(const char *p1, const char*p2)
    {
    	assert(p1 != NULL);
    	assert(p2 != NULL);
    	char* s1 = NULL;
    	char* s2 = NULL;
    	char* start = (char*)p1;//p1是const类型,受保护的指针,需要进行类型转换
    	if (*p2 == '\0')
    	{
    		return (char*)p1;//注意强制类型转换
    	}
    	while (*start)
    	{                     
    		s1 = start;//start的作用相当于使s1的每个字符和s2进行比较
    		//例如:s1=abbbcdef   s2=bbc,这种情况下,strat使s1每次移动一个字符
    		//使用的范围更广,而不是只适用于在两个字符串相同位置字符串相等的情况
    		s2 = (char*)p2;//同理上面的p1
    		while ((*s1 != '\0')&&(*s2 != '\0') && (*s1 == *s2))
    		{
    			s1++;
    			s2++;
    		}
    		if (*s2 == '\0')
    		{
    			return start;//找到子串
    		}
    		if(*s1=='\0)//p1的长度小于p2,提前终止
    	{
    		return NULL;
    	}
    		start++;
    	}
    	return NULL;//找不到子串
    }
    int main()
    {
    	const char* p1 = "abbbcdef";
    	const char* p2 = "bbc";
    	char*ret=my_strstr(p1, p2);
    	if (ret == NULL)
    	{
    		printf("字符串不存在");
    	}
    	else
    	{
    		printf("%s\n", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    bbcdef
    
    • 1

    strtok:charstrtok(charstr,const char*sep)

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

    举例:char arr[] = "zpw@bitedu.tech";
    char*p = (char*)"@.";//这里的@和点就作为分隔符的字符
    
    • 1
    • 2

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

    举例:char arr[] = "zpw@bitedu.tech";//arr为我们指定的字符串
    
    • 1

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

    举例:char arr[] = "zpw@bitedu.tech";
    char*p = (char*)"@.";//这里的@和点就作为分隔符的字符
    //找到第一个分隔符@,用\0结尾,继续寻找第二个分隔符.再用\0结尾
    
    • 1
    • 2
    • 3

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

    举例:char arr[] = "zpw@bitedu.tech";
    char*p = (char*)"@.";//当找到第一个分隔符@之后,strtok函数会记住该位置
    //下次寻找的时候就是从@后面的位置开始
    
    • 1
    • 2
    • 3

    5:strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
    6:如果字符串中不存在更多的标记,则返回NULL指针。
    那么它是如何使用的呢?
    举例:

    #include
    int main()
    {
    	char arr[] = "zpw@bitedu.tech";
    	char *p = (char*)"@.";
    	char* ret = NULL;
    	char* ptr = NULL;
    	for (ret= strtok_s(arr, p,&ptr); ret != NULL;ret=strtok_s(NULL,p,&ptr))
    	//第一次找到分隔符zpw之后,strtok_s函数会记住这个位置,下次直接从它后面的这个字符开始查找
    	{
    		printf("%s\n", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    zpw
    bitedu
    tech
    
    • 1
    • 2
    • 3

    strerror:char*strerror(int errnum)

    该函数的作用即为返回错误码,所对应的错误信息。

    举例:

    传递0:

    #include
    #include//该函数所必须包含的头文件
    int main()
    {
    	char* str = strerror(errno);//errno是一个全局的错误码的变量,当C语言的库函数在执行过程中,发生了错误,就会把对应的错误码,赋值到errno中
    	printf("%s\n", str);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    传递0:

    char* str = strerror(0);
    
    • 1
    No error
    
    • 1

    传递1:

    char* str = strerror(1);
    
    • 1
    operation not permitted
    
    • 1

    传递2:

    char* str = strerror(2);
    
    • 1
    No such file or directory
    
    • 1

    传递3:

    char* str = strerror(3);
    
    • 1
    No such process
    
    • 1

    不同的错误码对应的错误信息不同。

    那么它的作用如何体现呢?

    举例:

    #include
    #include
    int main()
    {
    	FILE*pf=fopen("test.txt", "r");
    	if (pf == NULL)
    	{
    		printf("%s\n", strerror(errno));
    	}
    	else
    	{
    		printf("open file success\n");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果该路径下,不包含该名为test的文件,输出结果为:

    No such file or directory
    
    • 1

    成功创建后,输出结果为:

    open file success
    
    • 1

    字符分类函数:

    函数--------------如果它的参数符合下列条件就返回真
    在这里插入图片描述

    举例:

    #include
    #include//islower函数包含的头文件
    int main()
    {
    	char ch = 'w';
    	int ret=islower(ch);//判断ch是否为小写字母
    	printf("%d\n", ret);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出结果为一个非零的数字:

    2
    
    • 1

    将ch改为大写字母:

    char ch = 'W';
    
    • 1

    输出结果为:

    0
    
    • 1

    字符转换函数:

    比较常见的两个就是:

    tolower(将字符转换为小写字母)/toupper(将字符转换为大写字母)

    举例:

    #include
    #include
    int main()
    {
    	char ch = tolower('Q');
    	putchar(ch);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出结果为:

    w
    
    • 1
    #include
    #include
    int main()
    {
    	char ch = toupper('s');
    	putchar(ch);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    S
    
    • 1

    对字符串中的某些字符进行转换:

    举例:

    #include
    #include
    int main()
    {
    	char arr[] = "I love china";
    	int i = 0;
    	while (arr[i])
    	{
    		if (isupper(arr[i]))//如果字符串中的字符为大写字母,则进入转换
    		{
    			arr[i] = tolower(arr[i]);
    		}
    		i++;
    	}
    	printf("%s\n", arr);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    i love china
    
    • 1
  • 相关阅读:
    机器人控制算法八之路径规划算法:RRT、RRT-Connect、Dynamic-Domain RRTs*
    程序员如何“升级打怪”?我用了这几个“歪瓜”!
    记录一次扩ubuntu的文件系统的过程
    部署java程序的服务器cpu过高如何排查和解决
    编程小白的自学笔记十七(python办公自动化操作EXCEL表格之作图)
    【开题报告】基于SpringBoot的膳食营养健康网站的设计与实现
    【附源码】计算机毕业设计SSM摊位管理系统
    还在刷面试题?NO 这次是这份Java面试通关手册才是你急需的
    ❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)
    「Android」浅析viewBinding和DataBinding
  • 原文地址:https://blog.csdn.net/m0_64365419/article/details/126061254