常见字符串函数及模拟字符串函数

目录

长度不受限制的字符串

strlen函数介绍及模拟实现

strcpy函数介绍及模拟实现

strcat函数介绍及模拟实现

strcmp函数介绍及模拟实现

长度受限制的字符串

strncmp函数介绍及模拟实现

strncpy的函数介绍及模拟实现

strnact函数介绍及模拟实现

字符串查找函数

strstr函数介绍及模拟实现

strtok函数介绍


长度不受限制的字符串

strlen函数介绍及模拟实现

strlen是一个库函数用来计算字符串长度,参数为const char*str用来接收要计算长度的字符串,且由于计算字符串长度不需要改变字符串内容所以用const来修饰。strlen返回值为无符号数,返回值就是要计算的字符串长度。

strlen:用来求字符串长度的函数 

  • 字符串以\0结尾,strlen是计算\0前面的字符串长度不包含\0,例如字符串"abcdef"包含a,b,c,d,e,f,\0  但strlen计算的答案不包含\0,所以长度为6;

  • strlen参数为常量字符串,指针指向的内容不可变(因为求字符串长度不需要改变字符串);
  • strlen返回值为无符号数。

 如果为避免出现上述错误我们应该避免相减判断。以后要时时刻刻注意strlen返回值为无符号数。

  • 模拟实现strlen
//计时器的方法
int my_strlen(const char* str)
{
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

//不能创建临时变量计数器
int my_strlen(const char* str)
{
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

//指针-指针的方式
int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}

strcpy函数介绍及模拟实现

strcpy为字符串拷贝函数,用来将源字符串拷贝到目标字符串,要注意的是将源字符串的\0也拷贝到目标字符串中。所以目标字符串空间必须足够大为避免溢出,目标空间也必须可修改,不能用const来修饰。

  • 注意
  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变
  • strcpy模拟实现
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest &&src);//断言一下防止为空指针
	while ((*dest++ = *src++))//这里将源字符串拷贝到目标字符串,还要记得最后要将\0也要拷贝到目标字符串
	{
		;
	}
	return ret;//返回目标字符串的起始地址
}

strcat函数介绍及模拟实现

strcat是用来追加字符串的一个函数,将源字符串追加到目标字符串的后面,所以目标空间必须足够大,且目标字符串必须可修改。

  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);//断言防止为空指针
	while (*dest)//一直到\0在追加源字符串
	{
		dest++;
	}
	//在目标字符串的结尾开始追加源字符串
	while ((*dest++ = *src++))//将源字符串追加到目标字符串的后面
	{
		;
	}
	return ret;//返回目标字符串的起始地址
}

strcmp函数介绍及模拟实现

strcmp用来字符串比较函数,从第一个字符开始比较,如果第一个字符相等就接着比较下一个字符,直到字符串结尾,结束比较。因为两个字符串只进行比较不用改变字符串,用const来修饰。当第一个字符串大于第二个字符串就返回大于0的数,当第一个字符串小于第二个字符串就返回小于0的字符串,当第一个字符串等于第二个字符串则返回数字0.

 strcmp的返回值

第一个字符串大于第二个字符串就返回大于0的数字。

第一个字符串等于第二个字符串的时候就返回等于0的数字。

第一个字符串小于第二个字符串就返回小于0的数字。 

strcmp的模拟实现

//模拟实现strcmp
int my_strcmp(const char* str1, const char* str2)
{
	while(*str1 == *str2) {
		if (*str1 == '\0') {//如果有一个字符串为空字符串就不用比较了
			return 0;
		}
		str1++;//否则的或对比每一个字符
		str2++;
	}
	if (*str1 > *str2) {//如果第一个字符大于第二个字符就返回大于0的数字
		return 1;
	}
	else//相反就返回小于0的数字
	{
		return -1;
	}
}

长度受限制的字符串

strncmp函数介绍及模拟实现

 strncmp对比strcmp函数长度受限制,可以任意对比字符串。与strcmp功能类似就是可以选定要比较字符串的个数。

strncmp的模拟实现

int my_strncmp(const char* str1, const char* str2, int n)
{
	while (n--)
	{
		if (*str1 > *str2)
			return 1;
		else if (*str1 < *str2)
			return -1;
		str1++;
		str2++;
	}
	return 0;
}

strncpy的函数介绍及模拟实现

strncpy 

如果拷贝个数大于源字符串个数,会将剩下的字符(拷贝的个数不是源字符串的个数)主动放上\0补充。

如果拷贝个数小于源字符个数直接将字符拷贝到目标字符串上去。

如果拷贝个数等于源字符串个数结尾最后不将\拷贝上去

对比strcpy,strncpy在strcpy上进行优化,使用更加灵活

strcpy和strncy的缺陷_l477918269的博客-CSDN博客_strcpy 缺陷

这篇文章主要讲strcpy的缺陷问题,

一是strcpy不能覆盖拷贝,一是字符串太长容易造成越界访问。

strncpy模拟实现

char* my_strncpy(char* dst, const char* src, int n)
{
	int i;
	for (i = 0; src[i] && i < n; i++)
	{
		dst[i] = src[i];
	}
	if (i < n)//如果拷贝个数大于源字符串个数就补上\0,总之拷贝的个数加上\0的个数等于n
	{
		dst[i] = 0;
	}
	return dst;
}

strnact函数介绍及模拟实现

strncat会将末尾放上\0

如果拷贝个数大于源字符串个数,在末尾放上\0,后面的不动。

如果拷贝个数小于源字符个数,在末尾会放上\0;

 strncat的模拟实现

char* my_strncat(char* str, const char* substr, int num) {
	char* ret = str;
	assert(str && substr);
	while (*str) {
		str++;
	}
	int i = 0;
	for (i = 0; substr[i] && i < num; i++) {
		str[i] = substr[i];
	}
	str[i] = 0;
	return ret;
}

字符串查找函数

strstr函数介绍及模拟实现

strstr这个函数是查找一个字符串的子串,如果查找到了就返回这个查找的字符串的首地址,例如在字符串abbbbcdef中查找bbc查找到就返回bbcdef,如果没有找到就返回空指针。 

strstr模拟实现

怎么查找呢?假如我们在abbbcdef中查找bbc

我们可以利用指针分别指向两个字符串,移动这两个指针进行对比,我们不能用str和substr因为两个指针与需要移动所以只能在定义两个指针。但是还有一个问题如果对比两个字符串不相等怎么办,那我们必须回到上一次比较的位置的下一个字符进行再一次比较然后指向bbc的指针需要重新回到指向第一个字符的位置,所以我们就在需要一个指针来记录上一次比较的位置,然后防止下一次重新比较。


char* my_strstr(const char* str, const char* substr)
{
	const char* s1 = str;
	const char* s2 = substr;
	const char* cur = str;
	assert(str && substr);
	if (*substr == '\0') {
		return (char*)str;
	}
	while (*cur) {
		s1 = cur;
		s2 = substr;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
			s1++;
			s2++;
		}
		if (*s2 == '\0') {
			return(char*)cur;
		}
		cur++;
	}
	return NULL;
}
int main()
{
	char str[] = "abbbdbbddef";
	char substr[] = "bd";
	char* ret = my_strstr(str, substr);
	if (NULL == ret) {
		printf("找不到\n");
	}
	else {
		printf("%s", ret);
	}
	return 0;
}

strtok函数介绍

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

strtok使用

int main()
{
	const char* p = "~!@#$%^&*.";
	char buff[50] = "wanger#12.iu~loi!lop*itre$hi";
	char* str = NULL;
	for (str = strtok(buff, p); str != NULL; str = strtok(NULL, p))
	{
		printf("%s\n", str);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值