目录
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 == str2 | 0 |
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,如有问题,请各位大佬多多指教!