字符串的库函数使用和实现(一)
前言
本文将详细介绍字符串及其库函数的使用及实现方式
一、简单字符串库函数
1、求字符串长度 — strlen
库函数的标准写法:size_t strlen( const char *string )
strlen这个函数返回值是size_t无符号整型,传递的参数是数组首元素的地址,看下面代码
#include<string.h>
#include<stdio.h>
int main()
{
char arr1[] = "abcdef";
char arr2[]= "cdef";
unsigned int ret1 = strlen(arr1);
unsigned int ret2 = strlen(arr2);
//其实无符号数有个bug,就是我如果想用strlen函数比较两个字符串大小
if(ret1-ret2>0)
printf("大于\n");
else if (ret1 - ret2<0)
printf("小于\n");
else
printf("等于\n");
return 0;
}
当我们自己实现该库函数的时候,有几个方向需要去思考:首先,strlen的返回类型和函数参数是什么?返回类型用int才可以比较字符串的大小(用size_t其实也是有道理,因为字符串压根不可能是负数),函数类型依然是字符首元素地址。第二,strlen函数如何实现,其实就是从字符串开始一直往后遍历到\0,记录有几个值然后返回就好了,看以下代码
#include<stdio.h>
#include<assert.h>
my_strlen(const char* parr)
{
assert(parr);//防止parr是空指针
int count = 0;
while(*parr)
{
count++;
parr++;
}
return count;
}
int main()
{
char arr[]="abcdef";
printf("%d",my_strlen(arr));
return 0;
}
2、字符串的拷贝 — strcpy
首先来看下标准库对该函数的描述:char *strcpy( char *strDestination, const char *strSource );
可以看到,函数的返回类型是char *, 函数参数是数组首元素地址,其中,第一个是要目标字符串,第二个是源字符串。看以下代码
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20]="hello";
char arr2[]="world";
printf("%s\n",strcpy(arr1,arr2));//因为会返回一个char*类型的数据,可以直接用%s来打印。
return 0;
}
有几个注意的点我说一下:
1、目标空间必须足够大
2、源字符串必须以 ‘\0’ 结尾
3、会将源字符串的’\0’拷贝到目标空间(看上图)
自己实现的时候要注意上面的问题,还有其实就是对应位置的交换就可以实现了,看以下代码:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* parr1, const char* parr2)
{
assert(parr1 && parr2);
char* start = parr1;
while(*parr2)
{
*parr1++ = *parr2++;
}
*parr1 = *parr2;//传\0
return start;
}
int main()
{
//注意1:要拷贝到的数组一定要足够大,能放得下拷贝的元素
char arr1[]="hello";
char arr2[]="world";
printf("%s\n",my_strcpy(arr1,arr2));
return 0;
}
3、字符串的追加 — strcat
首先来看下标准库对该函数的描述:char *strcat( char *strDestination, const char *strSource );
一看,和strcpy一摸一样,是不是,那我们看看实现的效果
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20]="hello";
char arr2[]="world";
printf("%s\n",strcat(arr1,arr2));
return 0;
}
有几个注意事项:
1、源字符串必须以 ‘\0’ 结尾
2、目标字符串的空间必须足够大
来实现一下这个函数:首先,先要找到第一个字符串的\0的位置,然后开始往后插入即可。
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* parr1 , const char* parr2)
{
assert(parr1 && parr2);
char* start = parr1;
while(*parr1)
{
parr1++; //找到parr1 \0的位置
}
while(*(parr1++) = *(parr2++))
{
;
}
return start;
}
int main()
{
char arr1[20] = "hello ";
char arr2[]="world";
printf("%s\n",my_strcat(arr1,arr2));
return 0;
}
是不是就可以很好的实现了?这个时候又有一个问题了,如果自己给自己追加呢,会不会出bug?
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello ";
char arr2[]="world";
printf("%s\n",my_strcat(arr1,arr1));
return 0;
}
会有bug,这个时候在实现(二)中讲strncat,这个时候就会有字符数量的限制,就可以很好的解决这个问题了。
4、比较两个字符串的大小 — strcmp
首先来看下标准库对该函数的描述:int strcmp( const char *string1, const char *string2 );
该函数返回类型是int,比较的两个字符串传入的都是首元素的地址。
返回>0 代表第一个字符串大于第二个字符串
返回=0 代表第一个字符串等于第二个字符串
返回<0 代表第一个字符串小于第二个字符串
来使用下这个库函数,看以下代码
#include<string.h>
#include<stdio.h>
int main()
{
char arr1[]="abcdef";
char arr2[]="bcdef";
printf("%d",strcmp(arr1,arr2));
return 0;
}
会输出一个小于0的数,说明arr1<arr2。
自己实现,首先分析,实际上呢,该函数是从第一个不相同的字符开始比较大小的,看以下实现代码:
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* parr1, const char* parr2)
{
assert(parr1 && parr2);
while (*parr1 == *parr2)
{
parr1++;
parr2++;
if (*parr1 == '\0')
return 0;
}
if (*parr1 > *parr2)
return 1;
else
return -1;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "cbcdef";
printf("%d", my_strcmp(arr1, arr2));
return 0;
}
总结
本文详细介绍了简单字符串的在库函数中的应用和自己的实现,很感谢看完全篇的每一位小伙伴,如果你觉得不错,请在屏幕上帮博主点个大大的赞,如果本文点赞过30个,2天后发出字符串系列二。