教你学会常见的字符串函数以及模拟实现

系列文章目录



前言

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组中.。字符串常量 适用于那些对它不做修改的字符串函数.


一、字符串函数是什么

字符串函数(String processing function)也叫字符串处理函数,指的是编程语言中用来进行字符串处理的函数

二、字符串函数包括哪些、如何模拟实现

1.求字符串长度函数

1.strlen函数的注意事项

1.字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
2.参数指向的字符串必须要以 ‘\0’ 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )。

2.strlen函数三种模拟实现的方法
int my_strlen(const char* arr) //1.计数器方式
{
  assert(arr);
	int count = 0;
	while (*arr != '\0')
	{
		count++;
		*arr++;
	}
	return count;
}
int main()
{
	char arr[] = "abc";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}
int my_strlen(const char* arr) //2.递归方式
{
  assert(arr);
	if (*arr != '\0')
	{
		return(1 + my_strlen(arr + 1));// arr+1意思是指针位置向后移一位
	}
	else
	{
		return 0;
	}
}
int main()
{
	char arr[] = "abc";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}
int my_strlen(const char* arr)  //3.指针减去指针是指针和指针中间的元素个数
{
	assert(arr);
	const char* start = arr;
	const char* end = arr;
	while (*end != '\0')
	{
		end++;
	}
	return end - start;
}
int main()
{
	char arr[] = "abc";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

2.长度不受限制的字符串函数

1.字符串拷贝函数
1.strcpy函数的注意事项

1.源字符串必须以 ‘\0’ 结束。
2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变。

1.strcpy函数的模拟实现
char* my_strcpy(char* arr1, const char* arr2)  //strcpy的模拟实现
{
	char* ret = arr1; //把起始地址存放到字符指针ret中
	while (*arr1++ = *arr2++)
	{
		;
	}
	return ret; //返回的是起始地址
}
int main()
{
	char arr1[] = "*****************";
	char arr2[] = "bit education";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}
2.字符串追加函数
1.strcat函数的注意事项

1.源字符串必须以 ‘\0’ 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。
3.目标空间必须可修改。
4.不能自己给自己追加。

2.strcat函数的模拟实现
#define _CRT_SECURE_NO_WARNINGS   1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* arr1, const char* arr2)
{
	assert(arr1&&arr2);
	char* ret = arr1;
	while (*arr1)
	{
		arr1++;
	}
	while (*arr1++ = *arr2++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "bit";
	char arr2[] = " education";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}
3.字符串比较函数
1.strcmp函数的注意事项

1.第一个字符串大于第二个字符串,则返回大于0的数字
2.第一个字符串等于第二个字符串,则返回0
3.第一个字符串小于第二个字符串,则返回小于0的数字

2.strcmp函数的模拟实现
int my_strcmp(const char* arr1, const char* arr2)  //1.一种模拟实现
{
	assert(arr1&&arr2);
	while (*arr1 == *arr2)
	{
		arr1++;
		arr2++;
	}
	if (*arr1 > *arr2)
	{
		return 1;
	}
	else if (*arr1 == *arr2)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}
int my_strcmp(const char* arr1, const char* arr2) //2.第二种模拟实现
{
	assert(arr1&&arr2);
	while (*arr1 == *arr2)
	{
		if (*arr1 != '\0')
		{
			return 0;
		}
	}
	return *arr1 - *arr2;
}
int main()
{
	char arr1[] = "bit";
	char arr2[] = "education";
	int ret = my_strcmp(arr1, arr2); //字符串比较函数
	printf("%d\n", ret);
	return 0;
}

3.长度受限制的字符串函数

1.字符串比较函数
1.strncmp函数的注意事项

1比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

2.字符串追加函数
1.strncat函数的注意事项

1.追加num个字符从源字符串到目标空间。
2.如果源字符串的长度小于num,追加完之后也会把\0追加过去,但如果字符不够不会补齐\0

2.strncat函数的模拟实现
char* my_strncat(char* arr1, const char* arr2, int count)
{
	assert(arr1&&arr2);
	char* ret = arr1;
	while (*arr1 != '\0')
	{
		arr1++;
	}
	while (count--)
	{
		if (!(*arr1++ = *arr2))
		{
			return ret;
		}
	}
	*arr1 = '\0';
	return ret;
}
int main()
{
	char arr1[30] = "bit ";
	char arr2[] = "education";
	my_strncat(arr1, arr2, 1);
	printf("%s\n", arr1);
	return 0;
}
3.字符串拷贝函数
1.strncpy函数的注意事项

1.拷贝num个字符从源字符串到目标空间。
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

2.strncpy函数的模拟实现
char* my_strncpy(char* arr1, const char* arr2,int nums)
{
	assert(arr1&&arr2);
	char* ret = arr1;
	while (nums) //拷贝arr2的字符到arr1里面去,剩余\0没有拷贝
	{
		*arr1++ = *arr2++;
		nums--;
	}
	while (nums) //拷贝\0过去
	{
		*arr1++ = '\0';
	}
	return ret;
}
int main()
{
	char arr1[20] = "***********";
	char arr2[] = "bit education";
	my_strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

4.字符串查找函数

1.字符串查找函数
1.strstr函数的注意事项

1.返回一个指针中str2在str1第一次出现的位置。

2.strstr函数的模拟实现
#define _CRT_SECURE_NO_WARNINGS   1
#include<stdio.h>
#include<string.h>
#include<assert.h>

//int main() //strstr查找子字符串
//{
//	char arr1[] = "bit education";
//	char arr2[] = "bit";
//	char* ret = strstr(arr1, arr2); //在arr1中查找arr2第一次出现的位置
//	if (ret != NULL)
//	{
//		printf("%s\n", ret);
//	}
//	else
//	{
//		printf("查找的字符串不存在!\n");
//	}
//	return 0;
//}

char* my_strstr(const char* arr1, const char* arr2)
{
	assert(arr1&&arr2);
	const char* cp = arr1;
	while (*cp)
	{
        const char* p1 = cp;
        const char* p2 = arr2;
		while ((*p1 != '\0') && (*p2 != '\0') && (*p1 == *p2))
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
		{
			return (char*)cp;
		}
		cp++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "bit education a";
	char arr2[] = "education";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else
	{
		printf("查找的字符串不存在!\n");
	}
	return 0;
}

如下图:
在这里插入图片描述

1.字符串分割函数

在这里插入图片描述

1.strtok函数的注意事项

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

2.strtok函数的实现
#define _CRT_SECURE_NO_WARNINGS   1
#include<stdio.h>
#include<string.h>
int main() //strtok根据字符来分割字符串
{
	char arr1[] = "1978045947@qq.com";
	char arr2[40] = { 0 };
	char* pa = "@.";
	strcpy(arr2, arr1);
	//printf("%s\n", strtok(arr2, pa));
	//printf("%s\n", strtok(NULL, pa));
	//printf("%s\n", strtok(NULL, pa));
	char* ret = NULL;
	for (ret = strtok(arr2, pa); ret != NULL; ret =strtok(NULL, pa)) 
	//1.第一次传非空指针,第二次传空指针 
	//2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
	//3.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
	{
		printf("%s\n", ret);
	}
	return 0;
}

5.错误信息报告函数

1.错误信息报告函数
1.strerror函数的注意事项

1.返回错误码,所对应的错误信息。

2.strerror函数的实现
#define _CRT_SECURE_NO_WARNINGS   1
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main() //strerror错误报告函数,库函数发生错误
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		perror(""); //相比strerror函数,perror封装了这些信息
	}
	return 0;
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了常用字符串函数的使用,而C语言中提供了大量能使我们快速便捷地处理数据的函数和方法,我们务必掌握,另外,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森明帮大于黑虎帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值