资讯专栏INFORMATION COLUMN

C语言-常用字符函数详解+模拟实现

elliott_hu / 2590人阅读

摘要:源字符串不修改,所以用修饰找到目标空间的位置跳出循环时,指向的就是目标空间的位置,从该位置向后追加,相当于作用字符串比较函数,是比较字符串的库函数,比较的是字符串的内容,不是长度。

 今天是2021年9月21日,首先祝大家中秋节快乐啦!但愿人长久,千里共婵娟。又是一年月圆,祝大家在中秋节都能和你爱的人和爱你的人团圆~

接下来进入整体啦~


目录

1.字符函数

strlen()

strcpy()

strcat()

strncpy()

strcmp()

strncat()

strncmp()

strstr()

strtok()

2.总结


下列函数都是包含在#include的库函数,若要使用,要现在最开始包含这个库


strlen()

1.作用:求字符串长度

  • 字符串以/0为结束标志,strlen()函数返回的是在字符串中‘/0’前面出现的字符个数(不包含/0) 

  • 参数指向的字符串必须要以/0结尾

  • 函数的返回类型为size_t,是无符号数

2.模拟实现:

方法1:计数器

size_t  my_strlen(const char* str){	size_t count = 0;	while (*str)	{		count++;		str++;	}	return count;}int main(){	char* str = "Mango";	size_t count = my_strlen(str);	printf("%u/n", count);	return 0;}

方法2: 指针-指针

指针-指针->得到的是二者相差的元素的个数  所以一个尾指针指向/0,一个指向起始位置,二者相减得到的就是字符串长度

size_t my_strlen(const char* str){	const char* start = str;	const char* end = str;	while (*end)	{		end++;	}	return end - start;}int main(){	char* str = "Mango";	size_t count = my_strlen(str);	printf("%u/n", count);	return 0;}

方法3:递归 

size_t my_strlen(const char* str){    //如果指向的不是/0,就+1(本身指向的字符),然后递归下一个字符	if (*str)	{		return 1 + my_strlen(str + 1);	}    //str指向的是/0就返回0	else	{		return 0;	}}int main(){	char* str = "Mango";	size_t count = my_strlen(str);	printf("%u/n", count);	return 0;}

strcpy()

 

1.作用:字符串拷贝,strcpy:拷贝的是源字符串开始向后直到/0前的内容

注意点:

  • 源字符串必须以/0结束
  • 会将源字符串的/0拷贝到目标空间

  • 目标空间必须足够大,以确保能存放源字符串

  • 目标空间必须可变


2.模拟实现

 注意点:源字符串不修改,所以用const修饰,返回类型为char*,返回的是目标空间的起始地址,所以定义一个指针保存起始地址,然后将src指向的内容拷贝到dest中

char* my_strcpy(char* dest,const char* src){    assert(dest&&src);    char* ret = dest;	//保存起始地址    while(*src)    {        *dest = *src;        dest++;        src++;           }    //上述只是完成了将src中/0之前的内容拷贝    //还要拷贝/0    *dest = *src;    return ret;}int main(){    char arr1[] = "xxxxxxx";    char arr2[] = "Mango";    char* ret = my_strcpy(arr1,arr2);    printf("%s/n",arr1);    printf("%s/n",ret);    return 0;}

简易写法:

char* my_strcpy(char* dest,const char* src){    assert(dest&&src);    char* ret = dest;	//保存起始地址    while(*dest++ = *src++)    {        ;    }    return ret;}

最后一次,src指向/0,把/0也拷贝过去之后,while判断表达式为假,跳出循环。  


strcat()

1.作用:字符串追加函数,从目标空间的/0位置开始向后追加源字符串


注意事项:

  • 源字符串必须以/0结尾

  • 目标空间也必须足够大,能容纳下源字符串的内容

  • 目标空间必须可修改

  • 不可以给自己追加!


2.模拟实现

思路:由于是在目标空间的/0位置开始向后追加,所以要先找到目标空间的/0位置,追加类似于strcpy过程,一个字符一个字符的追加,直到遇到源字符串的/0

注意:返回的是目标空间的起始地址,所以用指针变量保存它的地址。源字符串不修改,所以用const修饰

char* my_strcat(char* dest,const char* src){    assert(dest && src);	char* ret = dest;	//1.找到目标空间的/0位置	while (*dest)	{		dest++;	}	//跳出循环时,dest指向的就是目标空间的/0位置,从该位置向后追加,相当于strcpy	while (*dest++ = *src++)	{		;	}	return ret;}int main(){	char arr1[20] = "Mango";	char arr2[] = "Hello";	my_strcat(arr1, arr2);	printf("%s/n", arr1);	return 0;}


strncpy()


 strcmp()

1.作用:字符串比较函数,strcmp 是比较字符串的库函数,比较的是字符串的内容,不是长度比较的是两个字符串中,二者对应的第一个不相等字符的ascii码值大小, 比较的是/0之前的字符

 2.模拟实现

思路:遍历两个字符串,对应位置的字符比较是否相等,找到第一个二者对应不相等的字符,解引用,比较其对应的ascii码值

注意:当二者指向的字符相同时,判断其中一个指向的是不是/0,如果是,说明这两个字符串是一样的,

两个字符串只需要比较,不需要修改,所以用const修

int my_strcmp(const char* s1,const char* s2){    assert(s1 && s2);    //当二者指向的字符相同时,继续找,直到找到不相等的,或者其中一个为/0了,那就跳出循环    while(*s1 == *s2)    {        //先判断其中一个是不是/0,如果是,说明两个字符串是一样的,二者都指向了/0        if(*s1 == "/0")        {            return 0;        }        s1++;        s2++;    }    //找到指向不想等的字符了(或者一个为/0了),解引用比较对应的值    return *s1 - *s2;}int main(){	char arr1[] = "abcd";	char arr2[]  = "";	int ret = my_strcmp(arr1, arr2);	if (ret > 0)	{		printf("arr1 > arr2/n");	}	else if (ret < 0 )	{		printf("arr1 < arr2/n");	}	else	{		printf("arr1 = arr2/n");	}	return 0;}

strncat()

1,作用:字符串追加函数,和strcat的区别:此函数可以限制追加多少字节的内容

 当要追加的长度大于(小于)源字符串长度时,追加至源字符串/0位置即停止追加,追加结束后放入/0


2.模拟实现

 思路:

1.找到目标空间的/0位置

2.进行拷贝,共拷贝n次,(注意:拷贝过程中,有可能源字符串提前遇到/0,或者要拷贝的长度比源字符串长度长

3.进行判断count是否还>0,如果还>0,说明提前遇到/0,或者源字符串长度比要拷贝的长度短。这样的话,在目标空间追加完的下一个位置补/0

char* my_strncat(char* dest, char* src, size_t count){	assert(dest && src);	char* tmp = dest;	//1.找到目标空间/0位置	while (*dest!="/0")	{		dest++;	}	//跳出时,dest指向的就是/0,从此处开始拷贝	while (count-- && (*dest++ = *src++))	{		;	}    //追加结束后,补/0     //上面while拷贝完后,dest指向的是追加完成后的下一个位置,在此位置补/0		*dest = "/0";	return tmp;}int main(){	char arr1[20] = "Mango/0xxxxxx";	char arr2[] = "Lemon";	my_strncat(arr1, arr2, 2);	printf("%s/n", arr1);}

 strncmp()


 1.作用:

strncmp的功能和strcmp的功能和相似,只不过多了一个参数用来确定比较的个数

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


2.模拟实现

int my_strncmp(char* dest, char* src, size_t count){    assert(dest && src);    //找到前count个字符中,不相等的字符    while (count)    {        count--;        //二者指向相等,继续往下找        if (*dest == *src)        {            //若二者相等,且都是/0,则返回0            if(*dest == "/0")            {                return 0;            }            dest++;            src++;        }        else	//二者指向不相等,跳出循环            break;    }    //跳出时,找到不想等的字符,或者二者相等    return *dest - *src;}int main(){    char* str1 = "abcdef";    char* str2 = "abcd";    int ret = my_strncmp(str1, str2, 3);    if (ret > 0)    {        printf("str1>str2/n");    }    else if (ret < 0)    {        printf("str1 < str2/n");    }    else    {        printf("str1= str2/n");    }    return 0;}

strstr()

1.作用: 在一个主字符串找查找子字符串,如果找到了,反正子字符串在主字符串的起始位置,找不到,则返回空指针

注意:返回的是第一次出现的位置


2.模拟实现

 注意:遍历两个字符串进行比较,定义3个指针,一个指针用于遍历主字符串,一个指针用于遍历字符串,一个指针用于保存主串开始遍历的位置(方便后序返回子串在主串的起始位置)

当子字符串走到/0时,说明找到了,

当主子符串走到/0时,要么主字符串和子字符串相等,要么就是找不到

当子字符串为空字符串时,返回主字符串的起始地址(库函数就是这么写的)


 图解:

代码:

//返回子串出现在主串的第一个位置char* my_strstr(const char* str1, const char* str2){	assert(str1 && str2);	char* s1;	//用来遍历str1	char* s2;	//用来遍历str2	char* cp = str1;	//用于保存主子符串开始遍历的位置	//如果str2为空字符串,直接返回str1的地址	if (*str2 == "/0")	{		return str1;	}	//遍历主串与子串比较	while (*cp)	{		s1 = cp;	//s1从cp位置开始向后比较		s2 = str2;	//s2回到原始位置		while ((*s1 == *s2)&&*s1&&*s2)	//不仅要保证二者指向字符相等,还要保证s1和s2指向的不是/0		{			s1++;			s2++;		}		if (*s2 == "/0")		{			return cp;	//返回子串在主串的起始位置		}		else		{			//s1和s2指向不相等,cp指向下一个字符,然后下一次循环,把cp的值赋给s1用于下次遍历			cp++;		}	}	//跳出while循环时,说明主串都遍历完了,说明找不到->返回NULL	return NULL;}int main(){	char* str1 = "MangoLemon";	char* str2 = "an";	char* tmp = strstr(str1, str2);	char* tmpp = my_strstr(str1, str2);	printf("%s/n", tmp);	printf("%s/n", tmpp);	return 0;}

strtok()

1.作用: 字符串切割

  • 第二个参数是个字符串,定义了用作分割字符串的集合

  • strtok函数找到str中的下一个标记,并将其用/0结尾,返回一个指向这个标记的指针(注意:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容且可修改)

  • strtok函数的第一个参数不为NULL时:函数将找到str中第一个标记,strtok函数将保存它在字符串中位置

  • strtok的第一个参数为NULL时,函数将在同一个字符串中被保存的位置开始,查找下一个标志

  • 如果字符串中不存在更多的标志,就返回NULL


 例子:

 

 

int main(){    char arr1[] = "Mango@Lemon.Jiayou";    char arr2[100] = {0};	//防止strtok函数改变arr1中的数据,使用临时数组arr2	char sep[] = "@.";	//分割字符串的集合,即遇到@ 或者.就分割字符串    strcpy(arr2,arr1);    char* ret = NULL;    //分割字符串    //注意:第一次传传参为arr2,后序传参都传NULL    for(ret = strtok(arr2,sep); ret != NULL; ret = strtok(NULL,sep))    {        printf("%s/n",ret);    }    //相当于    //char* ret2 =strtok(arr2, sep);	//printf("%s/n", ret2);	//ret2 =strtok(NULL, sep);	//printf("%s/n", ret2);}

 2.总结

上述的函数中,

strcpy()         strcat()          strcmp()  

上述三个函数不够安全 长度不受限制的字符串函数。要么就一直追加/拷贝,直到遇到/0,或者一直比较,直到遇到不相等的字符


strncpy()   strncat()   strncmp()   

此三个函数可以控制字节数,相对安全!


 本文将持续更新那些博主今后遇到的其他的字符函数~欢迎关注!

如果感觉此文对你有帮助,请给博主一个三连吧!大家中秋节快乐!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/120820.html

相关文章

  • [C/C++]详解STL容器1--string的功能和模拟实现(深浅拷贝问题)

    摘要:本文介绍了类的常用接口的使用,并对其进行了模拟实现,对模拟实现中涉及到的深浅拷贝问题进行了解析。在此之前,必须提到一个经典问题。为了解决浅拷贝问题,所以中引入了深拷贝。但是实际使用中需要是第一个形参对象,才能正常使用。 本文介绍了string类的常用接口的使用,并对其进行了模拟实现,对模拟实...

    tianren124 评论0 收藏0
  • C语言-常用内存函数详解+模拟实现

    前言:博主之前有已经写过了C语言常用字符函数详解+模拟实现,感兴趣的同学可以去围观一下哦! 目录 前言: 1.内存函数 memcpy()  memmove() memcmp() memset() 2.错误信息报告函数 strerror()  perror() 1.内存函数 memcpy() 作用:内存拷贝 函数原型: 注意:count:要拷贝的字节数 函数memcpy从src位置开始向后赋值c...

    cucumber 评论0 收藏0
  • 手撕C语言进阶---字符串和内存函数(详解+实现+原码)

    摘要:自己实现时返回值可根据实际情况而定源字符串必须以结束。语言中给了一些长度受限的字符串函数,而前面的函数是长度不受限的字符串函数。拷贝个字符从源字符串到目标空间。 目录 字符函数和字符串函数 函数介绍 strlen strcpy strcat strcmp strncpy  strncat s...

    vslam 评论0 收藏0
  • 刨析C语言常用字符函数与内存函数模拟实现

    摘要:四函数字符串追加函数介绍函数的返回值类型为,可以返回被追加的字符串的起始地址。利用函数所需的头文件函数的使用代码运行结果为函数的特点及注意事项源字符串必须以结束。目标空间必须有足够的大,能容纳下源字符串的内容。 ...

    XBaron 评论0 收藏0
  • C语言-qsort函数详解

    摘要:目录一函数是什么二使用排序以升序为例关于型指针整形数组排序字符数组排序字符指针数组排序结构体数组排序浮点型数组排序三使用冒泡排序思想模拟实现函数什么是冒泡排序冒泡排序代码使用冒泡排序思想模 目录 一.qsort函数是什么  二.使用qsort排序-以升序为例       关于void*型指针...

    Airmusic 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<