手写strlen()、strcpy()、strcmp()、strcat()、strstr()、memcpy()

手写strlen()、strcpy()、strcmp()、strcat()、strstr()、memcpy()

一、int strlen(const char *str);

此函数是传入一个字符串,计算该字符串的长度,’\0’不算入其中。 (sizeof()才会把’\0’算入其中,但是sizeof()的功能是计算传入字符串所占的字节是多少)

int strlen(const char *str){
	assert(str != NULL);      //检查传入的字符串有没有申请空间
	int len = 0;              //定义字符串长度的计数变量
	while((*str++) != '\0')   //一直计算到'\0'的前一个字符为止
		len++;
	return len;               //返回字符串的长度(不包含'\0'的一个长度)
}

二、char* strcpy(char* str1, char* str2)

此函数是将str2复制到str1所指向的空间上。此函数不安全,容易产生内存越界(溢出),如果str2申请的空间比str1申请的空间大,就会产生此情况。

char* strcpy(char* str1, char* str2){
	assert((str1 != NULL)&&(str2 != NULL)); //检查传入的字符串有没有申请空间
	char * addr = str1;                     //首先记录str1字符串的首地址,为了后面返回用
	
	while((*str1++ = *str2++) != '\0');     //一直将str2的字符复制到str1的内存中去,直到复制完str2的'\0'空字符为止
	
	return addr;                            //返回str1的首地址
}

三、int strcmp(const char* str1, const char* str2)

此函数比较两个字符串是否相等,如果相等返回0,如果str1大于str2,返回正数,如果str1小于str2,返回负数

int strcmp(const char* str1, const char* str2){
	assert((str1 != NULL)&&(str2 != NULL)); //检查传入的字符串有没有申请空间
	
	int ret = 0;                            //定义返回值变量
	while(!(ret = *(unsigned char *)str1 - *(unsigned char *)str2)&&(*str1)){
		str1++;								//计算str1和str2的差值,如果差值为0,继续往后计算
		str2++;								//如果不为0,则退出循环。当str1指向'\0'时,退出循环。
	}
	
	if(ret > 0)								//大于0,返回1
		return 1;
	else if(ret < 0)						//小于0,返回-1
		return -1;
	else 
		return 0;                           //否则,返回0
}

四、char* strcat(char* str1, const char* str2)

此函数从str1字符串的’\0’位置开始将str2复制到str1后面。

char* strcat(char* str1, const char* str2){
	assert((str1 != NULL)&&(str2 != NULL)); //检查传入的字符串有没有申请空间
	
	char * addr = str1;						//首先记录str1字符串的首地址,为了后面返回用
	while((*str1++) != '\0');				//将str1指针指向最后一个空字符'\0'

	while((*str1++ = *str2++) != '\0');     //从空字符开始将str2复制进str1的内存空间

	*str1 = '\0';							//复制完后在最后的位置加上'\0'

	return addr;							//返回复制完后的首地址
}

五、char* strstr(const char* str1, const char* str2)

此函数用于判断str2是否是str1的子串,如果找到了就返回str1中中对应位置的起始地址,如果没找到就返回NULL。

char* strstr(const char* str1, const char* str2){
	assert((str1 != NULL)&&(str2 != NULL));	//检查传入的字符串有没有申请空间
	
	int str1len = strlen(str1);				//计算str1的长度
	int str2len = strlen(str2);				//计算str2的长度

	if(str1len < str2len)
		return -1;   						//这种情况就直接返回
	int i,j;
	
	for(i = 0; i<(str1len-str2len); i++){
		for(j = 0; j<str2len; j++){
			if(str1[i+j] != str2[j])		//循环判断str2是否是str1其中的子串
				break;
		}
		if(str2len == j)					//如果str2len的长度和j相等,证明str2是str1子串
			return str1+i;					//返回str1其中子串的起始地址
	}
	return NULL;							//失败返回NULL
}

六、void* memcpy(void* str1, const void* str2,int count)

该函数将str2的count个字节数据复制到str1存储区内。

void* memcpy(void* str1, const void* str2,int count){
	assert((str1 != NULL)&&(str2 != NULL));	//检查传入的字符串有没有申请空间
	
	char* STR1 = (char*)str1;
	const char* STR2 = (char*)str2;
	int i;
	
	if(STR1 > STR2&&STR1 < (STR2 + count)){
		for(i = count-1;i>=0;i--)
			STR1[i] = STR2[i];
	}
	else{
		for(i = 0;i < count;i++)
			STR1[i] = STR2[i];
	}
	return str1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思识己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值