strlen/str(n)cpy / str(n)cat / str(n)cmp函数

strlen

size_t strlen ( const char * str );

  • 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
  • 参数指向的字符串必须要以 ‘\0’ 结束
  • 函数的返回值为size_t,是无符号的

strlen("abc") - strlen("abcdef") > 0原因:
返回值为无符号数,则3-6=-3转换为无符号数为一个很大的正数
比较大小时,直接strlen("abc") > strlen("abcdef") 即可

  • 头文件为#include<string.h>

strlen函数的模拟实现

有三种实现方法my_strlen(返回类型可以是int,也可以是size_t
无符号数打印用%u

主函数

int main()
{
	printf("%d\n", my_strlen("abc"));
	return 0;
}
  1. 计数器的方式
int my_strlen(const char* str)
{
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
  1. 递归的方式
int my_strlen(const char* str)
{
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}
  1. 指针-指针的方式
int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}

strcpy

char* strcpy(char * destination, const char * source );
destination:目的地
source:来源

  • 将源指向的字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)
  • 源字符串必须以 ‘\0’ 结束
  • 会将源字符串中的 ‘\0’ 拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变
  • 头文件为#include<string.h>

strcpy函数的模拟实现

主函数

int main()
{
	char arr1[20] = "xxxxxxxxxxxxxxxxxx";
	char arr2[] = "abcdef";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	//printf("%s\n", my_strcpy(arr1, arr2));//简化
	return 0;
}
  1. 返回类型为char*是为了实现链式访问
  2. 返回值为目标空间的起始地址
  3. 防止目标地址和源地址为空指针,保证指针的有效性所以使用assert函数进行断言
  4. 目标地址可变,源地址不可变,所以用const进行修饰

my_strcpy函数

#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}

循环可以简化

简化后的my_strcpy函数

#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

strcat

char * strcat ( char * destination, const char * source );

  • 将源字符串的副本附加到目标字符串。目标中终止的null字符将被源的第一个字符覆盖,并且null字符将包含在目标中这两个字符串联形成的新字符串的末尾
  • 源字符串必须以 ‘\0’ 结束
  • 目标空间必须有足够的大,能容纳下源字符串的内容
  • 目标空间必须可修改
  • 字符串不可以自己给自己追加
  • 头文件为#include<string.h>

strcat函数的模拟实现

主函数

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

my_strcat函数

#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
		dest++;
	while (*dest++ = *src++)
		;
	return ret;
}

while (*dest) dest++;不可以简化为while(*dest++)

原因:
while(*dest++)循环结束后dest指向’\0’后一个空间
my_strcat函数的源地址需要将目标地址中的’\0’覆盖成它的第一个字符

strcmp

int strcmp ( const char * str1, const char * str2 );

  • 将字符串str1与字符串str2进行比较
  • 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下成对字符,直到字符不同或达到终止的null字符
  • 标准规定:
    第一个字符串大于第二个字符串,则返回大于0的数字
    第一个字符串等于第二个字符串,则返回0
    第一个字符串小于第二个字符串,则返回小于0的数字
  • 头文件为#include<string.h>

strcmp 函数的模拟实现

主函数

int main()
{
	int ret = my_strcmp("abc", "bbc");
	printf("%d\n", ret);
	return 0;
}

my_strcmp函数

#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}

*str1>*str2时,*str1 - *str2返回大于0的值
*str1<*str2时,*str1 - *str2返回小于0的值

长度不受限制,重点关注’\0’ ----- strcpy / strcat / strcmp


strncpy

char * strncpy ( char * destination, const char * source, size_t num );

  • 拷贝num个字符从源字符串到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
  • 目的地和来源不重叠
  • 头文件为#include<string.h>

strncat

char * strncat ( char * destination, const char * source, size_t num );

  • 将源的前num个字符追加到目标,再加上一个终止的null字符
  • 如果source中的C字符串的长度小于num,则只复制终止null字符之前的内容
  • 头文件为#include<string.h>

strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
  • 标准规定:
    第一个字符串大于第二个字符串,则返回大于0的数字
    第一个字符串等于第二个字符串,则返回0
    第一个字符串小于第二个字符串,则返回小于0的数字
  • 头文件为`#include<string.h>

长度受限制的字符串函数 ----- strncpy/strncat/strncmp


  • 30
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值