strlen strcpy strcat strcmp strncpy strncat strstr strtok等函数的使用及简单模拟

        最近学习了几个字符串函数,下面将进行简单的介绍以及简单模拟实现。

        觉得还不错的话,可以留下你的赞,给小编加加油。


一、strlen函数(求字符串函数)

        1.函数介绍

        size_t strlen ( const char * str );

        strlen是C语言中的的一个库函数,包含在头文件string.h中。strlen被用来求字符串的长度,统计的是‘\0’之前的字符个数。返回值size_t,无符号整数,意为字符串的长度是一个正整数。

        2.使用及简单模拟
//strlen函数的简单使用
#include<stdio.h>
#include<string.h> //头文件引用
int main()
{
	char arr[] = "abcdefg";

	printf("字符串长度为:%zd\n", strlen(arr));

	return 0;
}

        上面是strlen的使用,接下来小编将实现strlen函数的模拟,包括三个版本:

//strlen的简单模拟1
//利用第三变量实现
int my_strlen(char arr[])
{
	int count = 0;//创建一个计数器,来帮我们计数字符的个数
	int i = 0;
	while (arr[i] != '\0')
	{
		count++;//计数
		i++;
	}
	return count;
}

#include<stdio.h>
int main()
{
	char arr[] = "abcdefg";
	int ret = my_strlen(arr);//创建一个ret来接收函数的返回值
	printf("数组长度为:%d\n", ret);
	return 0;
}

        在这个代码中,通过创建第三变量count即计数器来帮我们在循环中对字符的个数进行计数,由于字符的大小为一个字节,故计数数目等于字符串长度。如果不创建变量又该怎样做呢?让我们来看看下面这段代码:

#include<stdio.h>
//strlen的模拟2
//不创建第三变量,通过递归实现
int my_strlen(char*p)
{
	
	if (*p == '\0')//判断第一个字符是不是'\0'
	{
		return 0;//是就返回0
	}
	else
	{
		return 1 + my_strlen(p + 1);//不是就返回1+此函数,并且地址向后走一位,进入递归
	}                               //中的向下"递"的过程,直到判断为0,再开始"归"的过程,并把数字1相加
}

int main()
{
	char arr[] = "abcdefg";
	int ret = my_strlen(arr);//创建一个ret来接收函数的返回值
	printf("数组长度为:%d\n", ret);
	return 0;
}

        在这呢,通过递归的方式解决了不使用第三变量的问题。我们已经学习过指针的有关知识,可不可以通过指针来实现strlen的模拟呢?答案是可以的:

#include<stdio.h>
//使用指针实现strlen的模拟
int my_strlen(char* p)
{
	//我们的思路是通过末尾字符的地址减首字符的地址得到字符个数
	char* e = p;//提前记录首字符的地址
	while (*p != '\0')
	{
		p++;
	}
	//当跳出循环是p已经是'\0'的地址
	return p - e;
}

int main()
{
	char arr[] = "abcdefg";
	int ret = my_strlen(arr);//创建一个ret来接收函数的返回值
	printf("数组长度为:%d\n", ret);
	return 0;
}

指针-指针可以得到两个地址间的元素个数,由此实现strlen的模拟。

二、strcpy的使用以及模拟实现

        1.函数介绍

        strcpy()包含在头文件string.h中,str-代表是字符串,cpy-是copy(复制)的意思,原型char* strcpy(char * destination, const char * source );功能是将source(源头)中的内容赋值拷贝到destination(目的地)中,并覆盖destination(目的地)中的内容,原因是将source(源头)字符串中的'\0'也拷贝了去。

2.使用以及简单模拟
#include<stdio.h>
#include<string.h>

int main()
{
	char str1[20] = "hello ";//为str1设定字符串大小大一点,以免
	                         //拷贝后发生溢出
	char str2[] = "I am Tom!";
	printf("拷贝前str1: %s\n",str1);
	strcpy(str1, str2);//将str2中的内容拷贝到str1中
	printf("拷贝后str1: %s\n", str1);
	return 0;
}

        看了strcpy的使用,接下来我们将实现strcpy的模拟:

#include<stdio.h>
#include<assert.h>
void my_strcpy(char* p1, const char* p2)
{
	assert(p1 != NULL && p2 != NULL);//assert断言,避免传来空指针
	while (*p2 != '\0')
	{
		*p1 = *p2;
		p1++;
		p2++;
	}
	//*p2为\0时已经跳出,在介绍中已经说过,'\0'也会拷贝,
    //所以这里需要再拷贝下'\0'
	*p1 = *p2;

}

int main()
{
	char str1[20] = "hello ";//为str1设定字符串大小大一点,以免
		                         //拷贝后发生溢出
	char str2[] = "I am Tom!";
	printf("拷贝前str1: %s\n",str1);
	my_strcpy(str1, str2);//将str2中的内容拷贝到str1中
	printf("拷贝后str1: %s\n", str1);
	return 0;
}

        在传参中,由于是将str2的内容拷贝到str1中str2不会变,故使用const去修饰。

三、strcat的使用及模拟实现

1.函数介绍

        char * strcat ( char * destination, const char * source ) ;

        可以看到,strcat跟strcpy有点像,是的,都是对字符串函数的处理。只不过strcpy是将source(源头)字符串拷贝到destination(目的地)字符串中并且覆盖目标字符串中的内容,而strcat是将source(源头)字符串剪切拼接到destination(目的地)字符串中,并不覆盖原内容。

2.使用以及简单模拟
//strcat的使用
#include<stdio.h>
#include<string.h>

int main()
{
	char str1[20] = "hello ";
	char str2[] = "I am Tom!";
	printf("拼接前str1:%s\n", str1);
	strcat(str1, str2);
	printf("拼接后str1:%s\n", str1);
	
	return 0;
}
拼接前str1:hello
拼接后str1:hello I am Tom!

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 12440)已退出,代码为 0。
按任意键关闭此窗口. . .

模拟实现:

//strcat的模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcat(char*p1,const char*p2)
{
	assert(p1 != NULL && p2 != NULL);
	//执行前判断指针的有效性
	char* e = p1;
	//参照strcpy的模拟思路,但又不能覆盖原有内容,故先将p1
	//指针向后移动到'\0'处,再进行拷贝,以达到链接的目的
	while (*p1 != '\0')
	{
		p1++;
	}
	while (*p2 != '\0')
	{
		*p1 = *p2;
		p1++;
		p2++;
	}
	*p1 = *p2;//最后将'\0'拷贝过去
	return e;
}

int main()
{
	char str1[20] = "hello ";
	char str2[] = "I am Tom!";
	printf("拼接前str1:%s\n", str1);
	char*ret = my_strcat(str1, str2);
	printf("拼接后str1:%s\n", ret);
	
	return 0;
}

效果是一样的:

拼接前str1:hello
拼接后str1:hello I am Tom!

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 428)已退出,代码为 0。
按任意键关闭此窗口. . .

四、strcmp的使用及模拟

1.函数介绍

        int strcmp ( const char * str1, const char * str2 );

        返回值是int(整型),若身str1大于str2则返回大于0的数,相等返回0,小于返回负数。那么如何判断两个字符串?实际上是⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。比如:str1: "abbc";   str2: "abcd"; 从第一个字符开始相比较a == a,向后走比较下一个字符,b == b,再走,b < c则str1小于str2,返回一个负数。这跟字符串长度是没有关系的,比如:str1:"abf";str2:"abcdef";str1是大于str2的,因为第三个字符'f'大于'c'。一旦比出了大小就不会再往后走,除非一直相等,则返回0。

2.使用以及简单模拟
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "abcdef";
	char str2[] = "abdcfe";
	int ret = strcmp(str1, str2);
	//用ret接收strcmp的返回值
	if (ret > 0)
	{
		printf("str1 > str2\n");
	}
	else if (ret = 0)
	{
		printf("str1 = str2\n");
	}
	else
	{
		printf("str1 < str2\n");
	}
	return 0;
}

使用起来还是很简单吧,那么接下来开始它的模拟实现吧!

#include<stdio.h>
#include<assert.h>

int my_strcmp(const char*p1,const char*p2)
{
	assert(p1 != NULL && p2 != NULL);
	while (*p1 == *p2)
	{
		//两个字符串都比完了还没分出大小,说明是相等的,返回0
		if (*p1 == '\0')
		{
			return 0;
		}
		p1++;
		p2++;
	}
	//跳出循环说明正在相比的两个字符不同,可以分出大小
	//返回两者的差值
	return *p1 - *p2;
}

int main()
{
	char str1[20] = "abcdef";
	char str2[] = "abdcfe";
	int ret = my_strcmp(str1, str2);
	//用ret接收strcmp的返回值
	if (ret > 0)
	{
		printf("str1 > str2\n");
	}
	else if (ret = 0)
	{
		printf("str1 = str2\n");
	}
	else
	{
		printf("str1 < str2\n");
	}
	return 0;
}

五、strncpy和strncat的使用

1.函数介绍

        char * strncpy( char * destination, const char * source, size_t num );

        char * strncat ( char * destination, const char * source, size_t num );

细心地小伙伴啊,可能已经发现了,这两个函数和前面的怎么那么像呢,其实啊这两个函数的功能和前面的相似,只不过多传了一个参数,致使他们可以按照使用者的意愿去拷贝或拼接指定数目的内容。而且,可能已经有人发现了,这里传参并不是int(整型),而是size_t(无符号整数),也就是我们常说的正整数,为什么是正整数呢?其实大家不妨想一想,你去拷贝或拼接的数目总不可能是一个负数吧。

2.简单使用

        需要注意的是在指定数目拷贝和拼接时,若拷贝或拼接的数目小于目的字符字符串的长度,则只改变前面的,后面不变,如下:

//strncpy
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "hello ";
	char str2[] = "I am Tom!";
	strncpy(str1, str2, 3);
	printf("%s\n", str1);

	return 0;
}
I alo

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 13348)已退出,代码为 0。
按任意键关闭此窗口. . .

是用str2中的I a拷贝替换了str1中的hel,str1后面的lo 是不变的。

strncat也是一样:

//strncat
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "hello ";
	char str2[] = "I am Tom!";
	strncat(str1, str2, 4);
	printf("%s\n", str1);

	return 0;
}
hello I am

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 12548)已退出,代码为 0。
按任意键关闭此窗口. . .

六、strstr的使用及模拟实现

1.函数介绍

        char * strstr ( const char * str1, const char * str2);

        函数返回字符串str2在字符串str1中第⼀次出现的位置,字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。就是在一个字符串str1中查找另一个字符串str2,并返回str2在str1中第一次出现的位置,可以打印。

2.简单使用以及模拟实现

        使用起来,效果如下:

//strstr 函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "abbbcdef";
	char str2[] = "bcd";
	char* ret = strstr(str1, str2);
	printf("%s\n", ret);
	return 0;
}
bcdef

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 22512)已退出,代码为 0。
按任意键关闭此窗口. . .

        这个函数的模拟相较之前几个会稍微难一些,我尽可能的阐述我的思路,请大家跟上不要掉队哦!

//strstr 函数的使用
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* p1, const char* p2)
{
	assert(p1 != NULL && p2 != NULL);
	const char* s1 = NULL;
	const char* s2 = NULL;
	//如果从cur这个地址这找到了str2,则需要返回cur,所以提前记录下
	const char* cur = p1;
	while (*cur)
	{
		s1 = cur;
		s2 = p2;//str2的内容查找,每次查找不成功时,str1地址向后走一位,而s2需要
		        //从头开始,所以我们在while循环中进行传址,这样每次循环都为重置为str2的首字符地址
		while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0')
		{//若在str1中找到了str2的第一个字符,则str1 str2都向后走一位,看下一位是否相同故需要while循环
		//若接下来不相同则跳出循环,想同且str2还未到'\0',则向后继续
		//若是在找完str2之前,str1已经走到了'\0',则也跳出循环
		//若是str1还有字符,而str2已经找完,说明str1中可以找到str2,则跳出循环返回之前记录的cur地址
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;//若*cur为'\0',还未找到,则说明str1中没有str2,返回NULL表示没有
}

int main()
{
	char str1[] = "abbbcdef";
	char str2[] = "bcd";
	char* ret = my_strstr(str1, str2);
	if (ret != NULL)
	{
		printf("找到了:%s\n", ret);
	}
	else
	{
		printf("没找到\n");
	}
	return 0;
}
找到了:bcdef

D:\编程\text_c\text_3.19-2\x64\Debug\text_3.19-2.exe (进程 4356)已退出,代码为 0。
按任意键关闭此窗口. . .

七、strcok、strerror的使用

1.函数介绍

        strcok:char * strtok ( char * str, const char * sep);

        sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合 。 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。 •strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容 并且可修改。)

        如果看不明白的话,不如来看看下面的例子,说不定就明白了:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "ni@hao@123.456.789.000";
	char* sep = ".@";//所有分隔符,无顺序要求
	char* str = NULL;
	//这里利用for循环的特点实现,不用多次重写
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	return 0;
}
//这个函数就是将字符串按所给的分隔符分开来

需要注意的是,在使用strcpy、strcat、strncat、strncpy时,需要注意目的字符串的大小,需要大一些,防止栈溢出。


        好了,就写到这了,如果小伙伴们觉得还不错的话,可以点赞关注加收藏来支持小编。

如有不对的地方,欢迎大家批评指正。小编将持续不定时的更新更多有关内容.........

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值