C语言strlen,strcpy,strcat,strcmp,strstr函数的自主实现:
注意:以下库函数都需要#include<string.h>头文件,包含assert函数的需要用到#include<assert.h>头文件。
1. strlen
strlen(字符串)——作用:计算字符串第一个’\0’之前的长度;
例:
char str[] = "abcde";
int len = strlen(str);
printf("%d \n", len);
结果为 5:
当字符串中含有’0’时,则计算’\0’之前的长度,例:
char str[] = "abc\0de";
int len = strlen(str);
printf("%d \n", len);
此时计算结果为3;
当我们需要自己去实现这个函数时,应该首先看看C语言标准库中strlen的定义方式
可以看到,strlen的返回类型是无符号整型size_t(int 也可以,根据情况使用),传参类型为const char*(const是不想改变原字符串的值防止误操作);因此,当我们在自主实现my_strlen的时候返回值也定义为整型(int)传参类型为const char*;同样的,当函数中传进来一个字符串名时,我们应当通过地址一个一个访问字符串中的内容并记录访问次数,直到遇到第一个’\0’返回访问的次数;下面是代码的实现:
//自主实现strlen
int my_strlen(const char* str)
{
int count = 0; //创建计数器
while (*str) //开始遍历 当*str == '\0' 时直接退出循环
{
str++;
count++;
}
return count; //返回计数
}
2. strcpy
strcpy(目标字符串 ,原字符串 ) ——作用:复制字符串(注意:目标字符串的大小必须和源字符串的大小相等或者更大,以保证有足够的空间存放原字符串的内容)
例:
char str0[] = "abcde";
char str1[10] = { 0 };
printf("%s\n", strcpy(str1, str0));
结果为:
strcpy标准库中定义方式:
strcpy函数会复制第一个’\0’之前的所有内容并返回目标函数的首地址,因此,我们在自主实现时应注意记录目标函数的首地址并在复制完成后返回;当然,在传入指针参数时我们可以加上assert函数来保证程序的正确性;以下为代码实现:
//自主实现strcpy
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest; //记录目标字符串地址
assert(dest && src); //防止程序出错 务必添加头文件#include<assert.h>
while (*dest++ = *src++)
{
;
}
return ret; //返回目标字符串地址
}
3. strcat
strcat(目标字符串 , 原字符串)——作用:将原字符串添加到目标字符串的后面(会覆盖’\0’);注意:strcat函数会自动将原字符串的’\0’添加到后面;
例:
char str0[] = "def";
char str1[10] = "abc";
printf("%s\n", strcat(str1, str0));
结果为:
strcat标准库中定义方式:
strcat返回类型为char*,因此同样需要一个地址来记录目标字符串的首地址;然后遍历目标字符串找到目标字符串的’\0’;然后将原字符串中的内容以目标字符串中’\0’的位置开始复制到目标字符串中;代码如下:
//自主实现strcat
char* my_strcat(char* dest, const char* src)
{
char* ret = dest; //记录目标字符串的地址为函数的返回做准备
assert(dest && src); //防止程序出错 务必添加头文件#include<assert.h>
while (*dest)
{
dest++; //遍历目标函数并找到其 '\0' 的位置
}
while (*dest++ = *src++) //复制原字符串内容包括'\0'至目标字符串中
{
;
}
return ret;
}
4. strcmp
strcmp(字符串1, 字符串2)——作用,把两个字符串进行大小比较,当字符串1<字符串2时返回小于0 的数,字符串1 = 字符串2时返回 0 ;字符串1 >字符串2时返回大于0 的数;
例:
char arr1[] = "abcde";
char arr2[] = "defgh";
int ret = strcmp(arr1, arr2);
if (ret == 0)
{
printf("arr1 = arr2");
}
else if (ret < 0)
{
printf("arr1 < arr2");
}
else
{
printf("arr1 > arr2");
}
结果为:
strcmp标准库中定义方式:
在这里我们需要有两个指针来分别遍历arr1和arr2并做出比较,通过比较当前位置的ASCII码值来返回相应的值;代码如下:
//自主实现strcmp
int my_strcmp(const char* str1 , const char* str2)
{
assert(str1 && str2);
int ret = 0;
while (!(ret = *(char*)str1 - *(char*)str2) && *str1) //遍历并做出比较,*str1 是为了在遍历到str1的'\0'时退出循环
{
str1++;
str2++;
}
if (ret < 0) // 小于返回复数
{
ret = -1;
}
else if (ret > 0) // 大于返回正数
{
ret = 1;
}
return ret;
}
5. strstr
strstr(字符串1 , 字符串2)——作用:在字符串1中找出整个字符串2出现第一次的位置并返回这个位置的指针,如果没找到,则返回空指针
例:
char arr1[] = "abcde";
char arr2[] = "cde";
printf("%s \n", strstr(arr1, arr2));
结果为:
strstr标准库中的定义;
首先我们需要分别对str1 和str2 进行遍历并比较,从str1的第一位开始与str2的每一位遍历并比较,并记录开始遍历时str1的首位地址,如果第一遍没找到,则继续向后进一位继续遍历,如果找到了,则返回所记录的地址,如果遍历结束都没找到,则返回NULL;
代码如下:
//自主实现strstr:
const char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1)
{
char* ret = (char*)str1; //记录字符串1每次开始遍历的地址
char* tmp = (char*)str2; //每次与字符串1做完比较后回到起始位置
while (*str1 == *tmp) //遍历
{
tmp++; //每有一位相等则继续向后遍历
str1++;
if (*str1 == '\0' && *str1 == *tmp) //若遍历到'\0'还相等则说明找到了
{
return ret; //返回找到时所记录的地址
}
}
str1++; //每遍历一次若没找到则继续
if(*str1 == '\0') //当字符串1遍历到'\0'还没找到就返回NULL
return NULL;
}
}