字符串函数

前言

一、常见字符串函数

1.strcpy

2.strcat

 3.strcmp

4.strtok

二、进阶版本

1.带个数函数的使用

2.strstr

三、总结


前言

在平常使用中对于字符串的操作是比较多的,经常会用到字符串大小的比较、拷贝甚至是查找以及各种类型数据的拷贝。熟练运用并掌握底层实现原理,有助我们拓宽思维,增强对语言的理解。

本文讲从介绍函数的使用以及详细的底层实现原理,来帮读者加深字符串函数的运用。

一、常见字符串函数

在C语言中,字符串规定为常量,表示不可对其修改,字符串变量是其首元素地址。

字符串函数都必须包含string.h头文件

1.strcpy

有字符串str1和字符串str2,如果我们想将字符串str1拷贝到str2中(假设str2空间足够大),我们无法使用简单的“="赋值操作符号。这将会是一个很麻烦的事情,库函数strcpy就实现这个繁琐操作。

先来看一下函数的接口

该函数有俩个参数,destination目的地和source源头,返回类型是char类型的指针

想将str1拷贝到str2中,只需要将str2传入第一个实参,str1传入第二个实参,用一个char类型指针接收结果。

注意:

  • 由于strcpy拷贝字符串,所以源头的字符串中必须要有'\0',编译器才能知道要拷贝到哪里停下
  • 目标空间要足够大(在vs编译器上,虽然能得出结果,但是程序会奔溃)

模拟实现strcpy

实现思想简单,俩个指针,一个循环,每次拷贝一个字节。拷贝完双指针各种一步

//模拟实现strcpy
char* my_strcpy(char* des, const char* sour)
{
	assert(des && sour);
	char* cur = des;
	while (*cur++ = *sour++)
	{
		;
	}
	return des;
}

2.strcat

字符串拷贝函数,会覆盖原有的字符串,strcat函数则是在目标字符串末尾追加源字符串

同样,函数接口与strcpy一致

 简单的举一个例子

 注意:

  • strcat追加函数的目标字符串和源字符串都必须有'\0',目标字符串的'\0'告诉编译器拷贝到哪里,源字符串的'\0'告知编译器拷贝哪里结束
  • 目标空间必须足够大(同样的能拷贝,但是程序会奔溃)
  • 不能自己给自己追加(自己给自己追加时,末尾的'\0'会被覆盖,程序会崩溃)

 模拟实现:

双指针,一个指针先指向sour的起始位置,一指针指向des的起始,des先走,直到找到'\0',

之后二者一起走

模拟实现strcat
char* my_strcat(char* des, const char* sour)
{
	assert(des && sour);
	char* head = des; //保存头指针
	while (*des++)
	{
		;
	}
	des--;
	while (*des++ = *sour++)
	{
		;
	}
	return head;
}

 3.strcmp

比较字符串大小的函数

  • 从首位开始比较,如果同一位上的数相同,则一起比较下一位,直到比出大小。
  • str1>str2-----返回大于0的数
  • str1<str2-----返回小于0的数
  • str1==str2---返回0

模拟实现

//模拟实现strcmp
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* s1 = str1;
	char* s2 = str2;
	while (*s1 == *s2)
	{
		s1++;
		s2++;
		if (*s1 == '\0')
		{
			return 0;
		}
	}
	return *s1 - *s2;
}

4.strtok

在一些特定的时候,要对字符串的内容进行分割。比如ip地址 192.168.10.1.1

要分割成四部分 192  168 10 1 1,自己实现就比较麻烦,strtok函数就可以轻松实现。

  •  strtok的第一个参数是需要分割的字符串,第二个参数是分割符
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
  • strtok会改变要分割的字符串,所以经常用一份字符串的拷贝来分割

strtok的用法是比较麻烦,下面就举个例子,来加深对strtok的用法

 通过strtok得到第一个分割符前的字符串abc;

由于第一个分割符号的位置已经被保存,所以第二次分割时,strtok的第一个参数因为空指针

 顺利分割出def,类似的在进行一次分割,就能得到字符串csdn

但是这样写,代码显得过于冗余,要我们下面将介绍一个巧妙的写法

 进入循环,第一次执行strtok,p被赋值为abc首元素地址,打印字符串,执行strtok(NULL,".,"),p被赋值为def的首元素地址

进入第二次循环,检查p是否为空,不为空打印字符串def。

依次打印,直到p为空。

二、进阶版本

1.带个数函数的使用

strcpy、strcmp、strcat默认跟进全部元素,在一定意义上,限制了函数的灵活,所以库函数提供更高的版本.strncpy,strcmp,strncat   就可以指定拷贝、比较、追加的字节个数

用法:在函数第三个参数传入要比较的字节数

strncpy

strncat

strncmp

用法与上面俩种相同,在第三个参数输入要比较的字节。

如果没有必到指定的字节,就出结果,那么就不需要比较了。

如果比完规定的字节没出结果,那么就返回0。

2.strstr

在很多时候,我们会在一堆字符串中寻找指定的字符串。strstr函数就可以返回字符串中指定串的起始位置,如果有多个满足要求的串,那么就返回第一起始位置

函数接口

 strstr函数的使用,很轻松就找到指定字符串,下面我们就来尝试写一个strstr函数

思路

例如:在str1="abbcdef",寻找str2="bcd"

首先一个指针cur找到第一个相同的位置,即在str1中,找到字符b的地址,

接着保存这个b的地址cur,然后再来俩个指针p1和p2,分别指向str1保存的位置和str2的起始位置

如果比对的字符都相同,让p1和p2都同时往后走,一旦有不同或者遇到'\0'就跳出这次比对

检查是否遇到'\0',否则就要开始新一轮的比对

让cur往后走,直到遇见第一个相同的元素,再进行新一轮的比对

如果cur指针将str1字符串都走完了,还没比对成功,那么就不存在符合要求的串,就返回空指针

接着就来看看代码

//模拟实现strstr
//abbcdef
//  bcd
#include<assert.h>
char* my_strstr(char* des, const char* sour)
{
	assert(des && sour);
	//双指针同时走
	char* cur1 = des;
	char* cur2 = sour;
	
	char* head = des;//保存起点
	while (*head)
	{
		cur1 = head;
		cur2 = sour;

		while (*cur1 == *cur2 && *cur1 && *cur2)
		{
			cur1++;
			cur2++;
		}
		if (*cur2 == '\0')//第二指针走到尾,找到了
		{
			return head;
		}
		head++;
	}
	return NULL;
}

三、总结

在运用上,strtok函数比较麻烦,在一次分割后,函数会保存起始位置,第二次分割时第一个参函数要为NULL。

在模拟实现,strstr相对麻烦,涉及到多个指针,俗话说“好记性不如烂笔头”大家可以动手比对一番,加深对函数的印象。

我是凡凡,一名努力学习C++的博主,如果有哪里不足的地方,请大家指出,我会认真反思!感谢大家的阅读。

代码++

offer++

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深度搜索

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

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

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

打赏作者

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

抵扣说明:

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

余额充值