字符函数和字符串函数

目录

一、strlen(计算字符串长度)

使用

模拟实现

第一种,创建临时变量count进行计数(不考虑空指针的情况)

第二种(指针相减)

第三种(递归法)

二、strcpy(字符串拷贝)

strcpy的使用

strcpy的模拟实现(不考虑空指针情况)

strncpy

strncpy模拟实现

注意事项

三、strcat(字符串拼接)

strcat

模拟实现

注意事项:

分析

代码实现

那么问题来了

strncat

模拟实现

分析

四、strcmp

模拟实现

五、strstr

使用

模拟实现


一、strlen(计算字符串长度)

使用

先来看看使用方式

int main()
{
	char arr[] = { 'a','b','c','\0'};
	size_t len = strlen(arr);
	printf("%zd\n", len);

	return 0;
}

注:需要引入头文件,

遇到\0就停止,

strlen()返回无符号的,

打印无符号整形用%zd。

#include<stdio.h>

结果为

模拟实现

模拟实现方法有很多这里介绍我学到的

第一种,创建临时变量count进行计数(不考虑空指针的情况)

分析

实现

size_t my_strlen(const char* str)//搞定参数和返回类型
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;

	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

结果

第二种(指针相减)

找到首元素和末元素进行相减

分析

实现

size_t my_strlen(const char* str)//搞定参数和返回类型
{
	char* start = str;
	while (*str) // '\0'可以去掉,a的asicc值不为0就进来了,到了\0就停止
	{
		str++;
	}
	//str已经到了字符串末尾位置
	return str - start;

}


int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

结果为6

第三种(递归法)

不使用临时变量,就字符串长度

​
size_t my_strlen(const char* str)
{
	if (*str=='\0')//如果第一个就是\0 就返回0
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}
int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

​

二、strcpy(字符串拷贝)

strcpy的使用

注意点:

源字符串必须有‘\0’

目标空间必须足够大

目标空间必须可修改,不能是常量字符串。

#include<string.h>
int main()
{
	char arr1[20] = "xxxxxxxxx";
	char arr2[] = "hello";
	strcpy(arr1,arr2);
	printf("%s\n", arr1);

	return 0;
}

strcpy的模拟实现(不考虑空指针情况)

分析

实现

char* my_strcpy(char* dest,char* src)//传过来arr1的首元素地址,用char*接收 ,返回char*,目标空间的首地址
{

	char* ret = dest;//先把dest的地址保存起来
					//将src的a放入dest开始
	//while (*src)	//直到src为\0时才停下来。
	//{
	//	*dest = *src;
	//	dest++;
	//	src++;
	//}


	//优化写法
	while (*dest++ = *src++)
	{
		;
	}
	return dest;
}
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

strncpy

strncpy模拟实现

​
实现strncpy
计算字符串大小,遇到\0就停止
把 src内n个元素拷贝到dest中
char* myStrncpy(char* dest, char* src, int n) 
{	
	int i = 0;    // 
	for (i = 0 ; src[i] != '\0' && i < n; i++)
	{
		dest[i] = src[i];

	}
	//问题:src中的\0有没有被拷贝
	//如果遇到‘\0’,则表示src[i] !=‘\0’为假, i<n为真的
	//需要手动把最后以为设置为\0
	if (i < n)
	{
		dest[i] = '\0';
	}	
	return dest;
}

int main()
{
	char dest[20] = { 0 };
	//char* dest = "abcdef";  这种做法是错误的,拷贝对象的必须的可修改的,最好是一个数组。
	char* src = "hello";
	char* ret = myStrncpy(dest, src, 3);
	printf("%s\n", ret);
	return 0;
}

​

将src中的n个字符串拷贝到dest中

注意事项

src中的‘\0’ 没有被拷贝进去,需要手动加进去。

三、strcat(字符串拼接)

strcat

模拟实现
注意事项:

源字符串必须以\0为结束,

目标空间也得有\0

目标空间必须可修改,足够大

分析

代码实现
char* my_strcat(char* dest,const char* src)//目标空间dest,源字符串src
{
	char* ret = dest;//保存起始位置
	//1.找到目标空间的\0
	while (*dest)
	{
		dest++;
	}

	//此时dest在\0处
	//然后开始拼接
	while (*dest++ = *src++)
	{
		;
	}

	return ret;
}

int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

至于const char* src为什么加const

因为src只需提供源字符串就可以了,不需要修改,即使改了,也不会报错。

那么问题来了

arr1 能不能给自己追加呢?

其实是不合适的,为什么呢?看图,形成了死循环。

strncat

模拟实现

分析

需要把src拷贝到dest的\0处,所以第一步就是找到dest的\0

第二步就是再\0处拷贝

第三步拷贝完了在手动加上\0

实现

​
//模拟实现strncat 拼接字符串

char* MyStrncat(char* dest, char* src, int n)
{
	char* tmp = dest;

	//1,找到dest的\0的位置
	while (*dest !='\0')
	{
		dest++; // 这样写会有一个问题就是dest一直++,就找不到初始位置了,所以需要用到chaar* tmp = dest;
	}
	//dest所指向的位置就是\0的位置
	int i = 0;
	//2.开始拷贝
	for (; i < n && src[i] != '\0'; i++)   // i<n表示拷贝n个,拷贝过程中src[i]就=\0了
	{
		dest[i] = src[i];//dest此处为\0,再\0上拷贝
	}

	if (i < n)
	{
		dest[i] = '\0';
	}
	return tmp;
}

int main()
{

	char dest[20] = "abcd";
	char* src = "hello";
	char* ret = MyStrncat(dest, src, 3);
	printf("%s\n", ret);
}

​

结果

四、strcmp

(字符串比较,比较的是ASCII码值的大小)

返回一个整形

第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
第⼀个字符串等于第⼆个字符串,则返回0
第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

模拟实现

int my_strcmp(const char* s1,const char* s2)
{
	//等于则进去++
	while (*s1 == *s2)
	{
		if (*s1 == '\0')//如果s1和s2都为\0就进这
		{
			return 0;
		}
		s1++;
		s2++;
	}
	//不等于就出来了来进行判断
	if (*s1 > *s2)
		return 1;
	else
		return -1;

}

int main()
{
	int ret = my_strcmp("abc","abd");
	if (ret > 0)
		printf("大于\0");
	else if (ret == 0)
		printf("等于\0");
	else
		printf("小于\0");
}

五、strstr

非常好用的一个函数

在一个字符串中找另一个字符串,并返回字符串str2在str1中第一次出现的位置。

使用

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

模拟实现

分析

s1 和 s2 进行比较

cur用来记录s1和s2相等时的起始位置

实现

char* my_strstr(const char* str1,const char* str2)
{
	char* cur = str1;//cur记录匹配时的起始位置。
	char* s1 = NULL;
	char* s2 = NULL;
	
	//如果str2第一个值就是\0
	if (*str2 == '\0')
	{
		return str1;
	}

	while (*cur)//cur不为0,如果cur是个空字符串还找什么找
	{
		s1 = cur;//把cur++的值赋给s1
		s2 = str2;//把str2回归初始值
		while (*s1 == *s2)//如果这一位相同,进入循环
		{
			s1++;
			s2++;
		}
		//b和\0不相同来到这
		if (*s2 == '\0')
		{
			return cur;
		}
		cur++;
	}

	//while循环找不到则返回null
	return NULL;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "bcd";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到");
	return 0;
}
  • 37
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值