C语言字符串函数strcmp、strstr的使用及模拟实现

目录

strcmp函数

strcmp函数的介绍

strcmp函数的使用

strcmp函数的模拟实现

strstr函数

strstr函数的介绍

strstr函数的使用

​strstr函数的模拟实现


strcmp函数

strcmp函数的介绍

C语言官方中,是这样介绍strcmp函数的。

函数的作用:

用于比较str1和str2字符串的大小的。

1. 第一个字符串大于第二个字符串,则返回大于0的数字。

2. 第一个字符串等于第二个字符串,则返回0。

3. 第一个字符串小于第二个字符串,则返回小于0的数字。

注:str1字符串和str2字符串是不能用 >、=、< 来比较的

举例,如下面程序

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcde";
	if (arr1 > arr2) 
	{
		printf("arr1 > arr2 \n");
	}
	else if (arr1 < arr2) 
	{
		printf("arr1 < arr2 \n");
	}
	else 
	{
		printf("arr1 == arr2 \n");
	}
    return 0;
}

我们可能会认为,这个会输出的是:arr1>arr2。但是实际结果如下:

                                          

这是为什么呢?

其实arr1和arr2都是数组名,数组名又是数组首元素的地址,所以arr1和arr2用 > = < 来比较,是比较的地址大小。

怎么来比较两字符串大小呢?

strcmp函数

strcmp函数就是用来比较两个字符串的,比较的就是两字符串中对应位置上字符的ASCII码值大的大小。

函数原型:

int strcmp(const char* str1,const char* str2);

我们来分析一下:

参数部分用const修饰,是因为仅仅是要str1和str2进行比较,不希望内容会被修改。

为什么strcmp函数的返回值是数字不像strlen,用size_t类型返回值呢?

这是因为它的返回值是有负数的

在VS环境下,列出下列代码:

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcde";
	int ret = strcmp(arr1, arr2);
	printf("str1 > str2——%d\n", ret);
	char arr3[] = "abcdef";
	char arr4[] = "abcdef";
	ret = strcmp(arr3, arr4);
	printf("str1 == str2——%d\n", ret);
	char arr5[] = "abcdef";
	char arr6[] = "abcdefg";
	ret = strcmp(arr5, arr6);
	printf("str1 < str2——%d\n", ret);
	return 0;
}

            

我们看到VS环境下,

    str1 > str2   1
    str1 == str20
    str1 < str2  -1

strcmp函数的使用

注意:使用时记得包含头文件string.h

#include<stdio.h>
#include<string.h> 
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdefg"; //举例abcdefg
	int ret = strcmp(arr1, arr2);
	if (ret > 0) 
	{
		printf("arr1 > arr2 \n");
	}
	else if (ret < 0)
	{
		printf("arr1 < arr2 \n");
	}
	else 
	{
		printf("arr1 == arr2 \n");
	}
    return 0;
}

我们来检查输出结果:

                                        

可以看出,要到我们预想到的结果。

注意:strcmp函数是比较两个字符串中的对应位置字符ASCII码值的大小,所以会出现下列这样的问题:

因为arr1中  g  与arr2中  f  对应,g  的ASCII码值大于  f  的,这样导致arr1>arr2。

strcmp函数的模拟实现

我们根据strcmp函数原型来定义一个自己的strcmp函数

int my_strcmp(const char* str1,const char* str2);

strcmp函数功能是比较两字符串对应位置字符ASCII码值大小,然后返回大于等于或小于0的数字。

模拟

//模拟
#include<assert.h>
#include<stdio.h>
int my_strcmp(const char* str1, const char* str2) //const修饰,因为仅仅比较俩字符串,不希望内容被改变
//为什么不用size_t返回类型,是因为返回值有负数。
//返回的是大于或小于或等于0的数字
{
	int ret = 0;
	assert(str1 && str2); //防止str1和str2指针为空
	while (*str1 == *str2) //当str1等于str2就往后走
	{
		if (*str1 == '\0') //相等返回0
			return 0;
		str1++;
		str2++;
	}
	if (*str1 > *str2)  //如果str1>str2则返回1
	{
		return 1;
	}
	else                  //如果str1<str2则返回-1
	{
		return -1;
	}
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdefg";
	int ret = my_strcmp(arr1, arr2);
	printf("ret = %d \n", ret);
	if (ret > 0)
	{
		printf("arr1 > arr2 \n");
	}
	else if (ret < 0)
	{
		printf("arr1 < arr2 \n");
	}
	else
	{
		printf("arr1 == arr2 \n");
	}
	return 0;
}

                           

在my_strcmp函数代码中,两字符串大于和小于可以优化一下:

#include<assert.h>
#include<stdio.h>
int my_strcmp(const char* str1, const char* str2)
{
	int ret = 0;
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2; //返回的是大于0或小于0的数字
}

                                        

可以看出,返回的ret是-103,一个负数,所以arr<arr2。

strstr函数

strstr函数的介绍

C语言官方是这样介绍strstr函数的:

函数的功能在一个字符串中查找另一个字符串是否出现过,若出现过则返回字符串str2在字符串str1中第一次出现的位置(地址),若没有出现返回的就是空指针。

注:函数的比较匹配不包含\0字符,以\0作为结束标志。

函数原型:

char * strstr ( const char * str1, const char * str2 );
//因为返回的是地址(位置),所以返回值用指针类型
//const修饰同上述strcmp
//函数功能:在str1中找str2

strstr函数的使用

注意:使用时记得包含头文件string.h

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

int main ()
{
  char str[] ="This is a simple string";
  char * pch;
  pch = strstr (str,"simple");       //在str中找smiple字符串,并返回第一次出现的位置让pch接收
  puts(pch);
  if (pch != NULL)                  //若pch不为空指针
    strncpy (pch,"sample",6);      //拷贝6个字符从sample字符串到指针pch里
  puts(pch);
  puts (str);                    //打印字符串str
  return 0;
}

我们查看输出结果

可以看出,这个函数返回的确实是字符串str2在字符str1中第一次出现的位置。

strstr函数其他使用示例

int main()
{
	char arr3[] = "abcdefabcdef";
	char arr4[] = "dio";
	char* ret = strstr(arr3, arr4);
	if (ret == NULL)
		printf("找不到\n");
	else
		printf("找到了  %s\n", ret);
	return 0;
}

int main()
{
	char arr1[] = "abcdefabcdef"; char arr2[] = "def";
	char* ret = strstr(arr1, arr2); 
	if (ret == NULL)
		printf("找不到\n"); 
	else
		printf("找到了  %s\n", ret);
	return 0;
	
}

strstr函数的模拟实现

根据函数的原型,来声明创建一个我的strstr函数

char* my_strstr(const char* strl,const char* str2);

在查找的时候可能会有三种情况:

首先,逻辑相对简单的

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

str2找到\0,说明存在,我们需要返回abcdef的b的地址,所以。

得有一个指针变量,记录开始匹配的位置

其次,逻辑复杂的

可能存在多次匹配。

当出现这种情况

还得有2个指针变量记录起始位置。

最后,找不到情况

	const char* s1 = NULL;  //用来存储str1
	const char* s2 = NULL; //用来后面存储str2
	const char* cur = str1; //记录当前位置的指针

       

根据这种思路,我们写出代码:

char* my_strstr(const char* str1, const char* str2)
{
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cur = str1; //记录当前位置的指针
	if (!*str2)  //若传过来的是空指针,则返回str1
		return ((char*)str1);  //要强制类型转化,将const char*转为char*
	while (*cur)
	{
		s1 = cur;
		s2 = str2;  //s2赋值str2,让s2指向str2首元素地址
		while (*s1 && *s2 && *s1 == *s2) //前提条件*s1,s2!='\0'说明俩都遇到字符串末尾,都没有结束
		{
			s1++;
			s2++;
			if (!*s2)  //找完了
			{
				return (cur); //返回cur记录的位置
			}
			
		}
		cur++; //如果不相等,cur向后移动一位
	}

}
int main()
{
	char arr1[] = "abcdefabcdef"; 
	char arr2[] = "def";
	char* ret = my_strstr(arr1, arr2); 
	if (ret == NULL)
		printf("找不到\n"); 
	else
		printf("找到了——%s\n", ret);
	return 0;
	
}

我们更改一下数组的元素

char arr1[] = "abcdefabcdef"; 
char arr2[] = "daw"

输出结果如下:

                ​​​​​​​        ​​​​​​​        ​​​​​​​        

若是空指针:

char arr2[]="";

输出结果如下:

        ​​​​​​​        

由此完成模拟实现strstr字符串函数。

制作不易,求各位大佬三连qwq,如有问题,请各位大佬多多指教!

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值