strlen与strcpy详解+模拟实现

举报
芒果_Mango 发表于 2022/02/26 21:38:18 2022/02/26
【摘要】 strlen -求字符串长度的库函数坑点:返回类型是size_t (sizeof返回类型也是size_t)字符串以\0为结束标志,strlen()函数返回的是在字符串中‘\0’前面出现的字符个数(不包含\0)参数指向的字符串必须要以\0结尾char arr[] = {'a','b','c'};strlen(arr); //err函数的返回类型为size_t,是无符号数int main()...

strlen -求字符串长度的库函数

image.png

坑点:返回类型是size_tsizeof返回类型也是size_t
  • 字符串以\0为结束标志,strlen()函数返回的是在字符串中‘\0’前面出现的字符个数(不包含\0)

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

    char arr[] = {'a','b','c'};
    strlen(arr);	//err
    
  • 函数的返回类型为size_t,是无符号数


int main()
{
	const char* str1 = "abcdef";
	const char* str2 = "abc";
	if (strlen(str2) - strlen(str1) > 0)
	{
		printf("str2 > str1\n");
	}
	else
		printf("str2 < str1\n");
	return 0;
}

打印结果:str2>str1

原因:strlen返回的是无符号数, 3 - 6 = -3被认为是无符号数,将-3对应的补码直接转化为十进制,得出的值>0


strlen()的模拟实现

方法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-字符串拷贝函数

image.png

int main()
{
    char arr1[] = "xxxxxxxx";
    char arr2[] = "hello";
    strcpy(arr1,arr2);
    printf("%s\n",arr1);
    return 0;
}

打印结果:hello

注意:arr2中的\0也拷贝了过去


int main()
{
    char arr1[] = "xxxxxxxx";
    char arr2[] = "he\0llo";
    strcpy(arr1,arr2);
    printf("%s\n",arr1);
    return 0;
}

打印结果:he

注意:如果arr对应字符串中提前有\0,则只拷贝\0之前的内容


strcpy:拷贝的是源字符串开始向后直到\0前的内容

  • 源字符串必须以\0结束

    char arr2[] = {'a','b','c'};
    char arr1[] = "xxxxxxx";
    strcpy(arr1,arr2);	//err
    
  • 会将源字符串的\0拷贝到目标空间

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

    char arr1[] = "xxx";
    char arr2[] = "hello\0abc";
    strcpy(arr1,arr2);	//err
    //原因:arr1的大小为4,根据后面初始化的内存缺点arr1的大小,空间太小,不足以存放arr2中\0之前的内容
    
  • 目标空间必须可变

    const char* p = "xxxxxxx";
    char arr2[] = "hello\0abc";
    strcpy(p,arr2);	//err
    //p为常量字符串不可以修改
    

模拟实现strcpy

注意点:源字符串不修改,所以用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;
}

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。