C语言中的字符串函数

目录

前言

字符串函数

strlen函数介绍及模拟实现

strlen函数介绍:

strlen模拟实现:

strcpy与strncpy函数介绍及模拟实现

strcpy与strncpy函数介绍:

strcpy与strncpy模拟实现:

strcat与strncat函数介绍及模拟实现

strcat与strncat函数介绍:

strcat与strncat模拟实现:

strcmp与strncmp函数介绍及模拟实现

strcmp与strncmp函数介绍:

strcmp与strncmp模拟实现:

strstr函数介绍及模拟实现

strstr函数介绍:

strstr模拟实现:

strtok函数介绍

strerror函数介绍

总结

后记


前言

C语言中有着许多字符串函数,使用这些函数可以对字符串进行各种各样的操作,本篇小鸥将从函数原型讲起,依次介绍字符串函数的返回值、参数、作用、使用方法、注意事项和模拟实现。

注:字符串函数的使用需要包含头文件。

#include <string.h>

字符串函数

strlen函数介绍及模拟实现

strlen函数介绍:

函数原型:

返回值:size_t(一种无符号整型,对应占位符为%zd)类型,返回的是计算的字符个数;

参数:const修饰的char* 类型的字符指针

作用:计算字符串长度;

使用:附代码:

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

int main()
{
	char arr1[] = "abc";
	char* pc1 = "strlen";
	size_t len = strlen(arr1);//arr1是数组名,指向首元素地址
	printf("%zd\n", len);

	printf("%zd\n", strlen(pc1));//指针的讲解中我们知道:pc1指向的就是"strlen"中字符s的地址

	char* pc2 = "str\0len";
	printf("%zd\n", strlen(pc2));
	return 0;
}

从上文的三个结果对比可以看出:strlen函数计算的是其参数指向的地址位置,到遇到第一个\0之前的所有字符的个数。当strlen函数遇到\0时就会停下来,并返回计算的字符总个数。

strlen模拟实现:

//1.计数器的方式
#include <stdio.h>
size_t my_strlen(const char* p)
{
	int count = 0;
	while (*p != '\0')
	{
		count++;
		p++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";

	size_t ret = my_strlen(arr);
	printf("%zd", ret);
	return 0;
}
//2.指针-指针的方式
#include <stdio.h>
size_t my_strlen(const char* p)
{
	char* pstrat = p;
	while (*p != '\0')
	{
		p++;
	}
	return (p - pstrat);
}

int main()
{
	char arr[] = "abcdef";

	size_t ret = my_strlen(arr);
	printf("%zd", ret);
	return 0;
}
//3.递归方法
#include <stdio.h>
size_t my_strlen(const char* p)
{
	if (*p != '\0')
	{
		return (1 + my_strlen(p + 1));
	}
	else
		return 0;
}

int main()
{
	char arr[] = "abcdef";

	size_t ret = my_strlen(arr);
	printf("%zd", ret);
	return 0;
}

strcpy与strncpy函数介绍及模拟实现

strcpy与strncpy函数介绍:

函数原型:

返回值:char*类型,返回的是目标空间的起始地址;

参数:strcpy:目标空间起始地址,源空间起始地址;

           strncpy:目标空间起始地址,源空间起始地址,限制长度;

作用:将源空间中的字符拷贝到目标空间中(strncpy可以自定义拷贝长度),并返回目标空间的起始地址;

使用及注意事项:

strcpy:

附代码:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "hello word!";

	char* ret = strcpy(arr1, arr2);
	//目标空间在前,源空间在后
	printf("%s\n", ret);
	printf("%s\n", arr1);

	return 0;
}

strncpy:

注意:

1.strcpy和strncpy的结束标志也都是\0,遇到第一个\0之后就结束拷贝,返回目标空间的起始地址;

2.目标空间的大小应该足够大;

3.strncpy函数在第三个参数num大于源空间字符串长度时,不够的会在用\0补齐,直到num个时停止;而num小于源空间函数时,只会拷贝相应个数的字符个数,且不会在拷贝的末尾加\0。

strcpy与strncpy模拟实现:

strcpy

#include <stdio.h>
#include <assert.h>
//模拟实现strcpy

char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);//断言是否为空指针
	char* ret = dest;
	while (*dest++ = *src++)
		;
	return ret;
}

int main()
{
	char arr1[] = "Hello world";
	char arr2[20] = "xxxxxxxxxxxxxxxx";
	char* ret = my_strcpy(arr2, arr1);
	printf("%s", ret);
	return 0;
}

strncpy

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);
	while (num--)
	{
		if (*src != '\0')//当num还没到0,源字符串也没到\0时,就给目标空间拷贝*src
		{
			*dest++ = *src++;
		}
		else if(*src == '\0')//若源空间先到\0,则在目标空间中补\0,直到num为0
			*dest++ = '\0';
	}

	return ret;
}

int main()
{ 
	char arr1[20];
	char arr2[] = "aafdsdsa";
	char* ret = my_strncpy(arr1,arr2,10);//当num小于源字符串时,不会在目标空间后补\0
	printf("%s", ret);
	return 0;
}

strcat与strncat函数介绍及模拟实现

strcat与strncat函数介绍:

函数原型:

返回值:char*类型,返回的是目标空间的起始地址;

参数:strcat:目标空间起始地址,源空间起始地址;

           strncat:目标空间起始地址,源空间起始地址,限制长度;

作用:在目标空间中追加源空间中的字符串(strncat可自定义追加长度),并返回目标空间的起始地址;

使用及注意事项:

strcat:

附代码:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello_";
	char arr2[] = "word!";

	char* ret = strcat(arr1, arr2);
	printf("%s\n", ret);
	printf("%s\n", arr1);

	return 0;
}

strncat:

注意:

1.由上文对比图可知,函数结束标志为\0,先找到目标空间中的第一个\0,然后再将源空间中的字符串追加到目标空间中,直到找到第一个\0为止结束;

2.目标空间的大小应该足够大;

3.strncat函数,当num大于源空间中字符串长度时,只会追加源空间字符串相应的长度,不会补\0以满足参数num的大小(和strncpy区别),而num小于源空间字符串长度时,只追加num相应长度的字符个数,然后自动在追加末尾加上\0。

strcat与strncat模拟实现:

strcat

#include <stdio.h>
#include <assert.h>
//模拟实现strcat

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest != '\0')//先找到需要进行追加字符串的目标地址中的\0,用于判断追加字符串的起始位置
		dest++;
	while (*dest++ = *src++)//和模拟strcpy时相同的方法将需要追加的内容追加到目标字符串的后面
		;
	return ret;
}

int main()
{
	char arr1[20] = "Hello ";
	char arr2[] = "wrold!";
	char* ret = my_strcat(arr1, arr2);
	printf("%s", ret);
	return 0;
}

strncat

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++)//dest指向\0后还会往后++一次
		;
	dest -= 1;//让dest回到\0的位置
	while (num--)
	{
		*dest++ = *src++;
		if (!(*(src-1)))//当src指向的字符串小于num时,*src追加给目标空间\0之前的最后一个数后,由于后置++
			return ret;//如果直接判断*src会导致\0没有追加到目标空间中,所以判断*src-1
	}
	*(dest + 1) = 0;//当num小于src指向的字符串时,追加结束在目标字符串后加上\0
	return ret;
}

int main()
{
	char arr1[20] = "Holle_";
	char arr2[] = "World!";
	char* ret = my_strncat(arr1, arr2, 8);
	printf("%s", ret);
	return 0;
}

strcmp与strncmp函数介绍及模拟实现

strcmp与strncmp函数介绍:

函数原型:

返回值:int类型,返回的值有三类 :1.字符串1大于字符串2时,返回大于零的数;2.字符串1=字符串2时,返回0;3.字符串1<字符串2时, 返回小于零的数;

参数:strcmp:字符串1的起始地址,字符串2的起始地址;

           strncmp:字符串1的起始地址,字符串2的起始地址,限制长度;

作用:比较两个字符串的大小 。

使用:

附代码:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello_";
	char arr2[] = "word!";

	char* ret = strcat(arr1, arr2);
	printf("%s\n", ret);
	printf("%s\n", arr1);

	return 0;
}

strncmp:

注意:

1.strcmp与strncmp两个函数在比较字符串大小时,是从参数传入的地址位置开始,一个字符一个字符的比较大小,本质是比较两个字符ASCII码的大小( \0的ASCII码值为0);

2.strncmp函数比较的长度就是由参数num决定的。

strcmp与strncmp模拟实现:

strcmp

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);//断言是否为NULL
	while (*str1 == *str2)//相等就继续比较下一个字符
	{
		if (*str1 == '\0')//相等且等于\0 则说明两个字符串相同
			return 0;//直接返回0
		str1++;
		str2++;
	}
	return *str1 - *str2;//不相等时返回差值
}

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

strncmp

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2,size_t num)
{
	assert(str1 && str2);//断言是否为NULL
	while (*str1 == *str2 && num)//相等就继续比较下一个字符
	{
		if (*str1 == '\0')//相等且等于\0 则说明两个字符串相同
			return 0;//直接返回0
		str1++;
		str2++;
		num--;
	}
	//当num为0时,str1和str2已经跳过了num个字符指向了第num + 1个字符
	//此时直接返回差值,返回的将是第num + 1个字符的差值,所以需要调整指针向前退一位
	return *(str1 - 1) - *(str2 - 1);//不相等时返回差值
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcf";
	int ret = my_strcmp(arr1, arr2, 3);
	if (ret > 0)
		printf("arr1>arr2");
	else if (ret == 0)
		printf("arr1=arr2");
	else
		printf("arr1<arr2");
	return 0;
}

strstr函数介绍及模拟实现

strstr函数介绍:

函数原型:

返回值:返回值是找到的第一个目标字符串(被查找字符串中可能不止包含一个待查找字符串)的起始地址,若没有查找到字符串则返回NULL;

参数:被查找字符串,待查找字符串;

作用:在被查找字符串中查找待查找字符串;

使用:

注意:

1.返回的是被查找字符串中找到的第一个待查找字符串的起始地址;

strstr模拟实现:

#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);//断言防止空指针
	const char* s1 = str1;
	const char* s2 = str2;
	const char* flag = str1;

	while (*flag)//当*flag为0时就表示没有目标字符串
	{
		s2 = str2;
		s1 = flag;
		while (*s1 == *s2 && s1 != '\0' && s2 != '\0')//当找到相同字符后,进入循环继续查看后面的字符是否相同
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')//上循环结束后,若s2指针指向的是\0则说明已经找到该字符串
			return (char*)flag;//返回该字符串的起始位置
		flag++;//若没有跳出
	}
	return NULL;//当s1指向\0时说明没有找到目标字符串,返回空指针
}

int main()
{
	char arr1[] = "abdagsadafe";
	char arr2[] = "sad";
	char* ret = my_strstr(arr1, arr2);//在arr1,中查找是否存在arr2中的字符串
	printf("%s", ret);
	return 0;
}

strtok函数介绍

函数原型:

返回值:返回的是每一次分割的字符段的首地址;

参数:被分割的字符串的地址,分隔符数组的地址;

作用:将被分割的字符串以分割符为界限分隔开(一次调用只能分割出一个字符段),并返回该次分割得到的字符段的地址;

使用及注意事项:

调用一次:

调用多次:(使用for循环)

附代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "fdhauifdaf@outlook.com";//含有分隔符的字符串
	char arr2[] = "@.";//分隔符集合
	
	char* ret = NULL;
	for (ret = strtok(arr1, arr2); ret != NULL; ret = strtok(NULL, arr2))
		printf("%s\n", ret);
	return 0;
}

注意:

1.strtok函数的原理时是:在找到一个分隔符后,将分隔符换为\0,并返回当前被分割字符段的起始地址;

2.strtok函数会记住当前调用时找到的分隔符的地址,因此第二次调用时若第一个参数为NULL时,strtok函数就会从记住的位置开始继续往后查找下一个分隔符,若没有查找到,就返回NULL;

3.在VS环境下要包含#define _CRT_SECURE_NO_WARNINGS;

strerror函数介绍

函数原型:

返回值:返回的是参数部分错误码对应的错误信息的字符串的地址;

(错误码和错误信息):

参数:错误码;

作用:返回错误码对应的错误信息的字符串的地址;

使用:

附代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	for (int i = 0; i <= 10; i++)
	{
		printf("%d:%s\n", i, strerror(i));
	}
	return 0;
}

图中就是每个错误码对应的错误信息(不止10个)。

注意:

在VS环境下要包含#define _CRT_SECURE_NO_WARNINGS;

总结

strlen函数:计算字符串长度(单位字节);

strcpr、strncpy函数:拷贝字符串;

strcat、strncat函数:追加字符串;

strcmp、strncmp函数:比较字符串大小;

strstr函数:在一个字符串中查找另一个字符出;

strtok函数:使用分隔符分割字符串;

strerror函数:获取错误码对应错误信息的地址;

后记

感谢各位读者的阅读,今天我们主要总结了各种字符串函数的用途和模拟,不足的地方请大家多多指教,我们下期再见!

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值