字符串函数——strlen/strcpy/strcat/strcmp/strncpy/strncat/strncmp/

strlen

    size_t strlen ( const char * str );
  • 返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
    含 ‘\0’ )。
  • 如果字符串未以 ‘\0’ 结尾,则沿着地址继续向后找,直到找到 ‘\0’ 为止,故返回随机值。
  • 返回值类型为 size_t,是无符号数。易错点如下:
int main(){
	const char* str1 = "abcdef";
	const char* str2 = "bbb";
	if (strlen(str2) - strlen(str1) > 0){	
            // str2>str1	因为-3被当成一个无符号数时,特别大
	//if(strlen(str2) > strlen(str1)){	
            // srt1>str2
		printf("str2>str1\n");
	}
	else{
		printf("srt1>str2\n");
	}
	return 0;
}

if的判断语句为

    strlen(str2) - strlen(str1) > 0

因值为 -3 被当作是无符号数时,远大于0,因此打印 str2>str1
if的判断语句为

    strlen(str2) > strlen(str1) 

因为 strlen(str2) < strlen(str1), 因此打印 srt1>str2

strlen模拟实现

  • 方法一:计数器count
size_t my_strlen(const char* str) {

	int count = 0;
	while (*str){
		count++;
		str++;
	}
	return count;
}
  • 方法二:递归
size_t my_strlen(const char* str) {
	if(*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}
	
  • 方法二:指针-指针
size_t my_strlen(const char* str) {
	char* p = str;
	while (*p != '\0')
		p++;
	return p - str;
}

strcpy

    char* strcpy(char * destination, const char * source );
  • 将源字符串 \0 前的字符(包括 \0 ),全部拷贝到目标空间,并返回目标空间起始地址
  • 源字符串必须以 \0 结尾
  • 目标空间(字符串)必须足够大,并且可变,故未用 const 修饰目标空间

strcpy模拟实现

char* my_strcpy(char* dest, const char* src) {
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++) {
		;
	}
	return ret;
}

strcat

    char * strcat ( char * destination, const char * source );
  • 将源字符串追加在目标空间,与 strcpy 相比,多了一步找目标空间的 \0, 放回的是目标空间的地址
  • 源字符串必须以 \0 结尾
  • 目标空间(字符串)必须足够大,并且可变,故未用 const 修饰目标空间

strcat模拟实现

// 与strcpy相比,多一个目标空间找 \0
char* my_strcat(char* dest, const char* src) {
	assert(dest && src);
	char* ret = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++ = *src++){
		;
	}
	return ret;
}

strcmp

    int strcmp ( const char * str1, const char * str2 );
  • 比较字符串中对应位置上字符的大小(ASCLL值),返回值如下:
    • 第一个字符串大于第二个字符串,则返回大于0的数字
    • 第一个字符串等于第二个字符串,则返回0
    • 第一个字符串小于第二个字符串,则返回小于0的数字

strcmp模拟实现

int my_strcmp(const char* dest, const char* src) {
	assert(dest && src);
	int ret = 0; 
	while (!(ret = *(unsigned char*)src - *(unsigned char*)dest) && *dest){
		++src, ++dest;
    }
	return ret;
}

strncpy

    char * strncpy ( char * destination, const char * source, size_t num );
  • 从目标空间起始地址开始,从源字符串拷贝num个字符到目标空间
  • 如果源字符串长度大于 num,则拷贝相应个数
  • 如果源字符串的长度小于 num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
  • strcpy 相比,除多了拷贝的字数 num,其余相同。

strncpy模拟实现

char* my_strncpy(char* dest, const char* src, size_t num) {
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++) {
		num--;
        // 拷贝num个字符后,跳出循环
		if (0 == num) {
			break;
		}
	}
    // 源字符串的长度小于num,后面追加\0
	while (num) {
		*dest++ = '\0';
		num--;
	}
	return ret;
}

strncat

    char * strncat ( char * destination, const char * source, size_t num );
  • 从目标空间起始地址开始,找到 \0 ,在 \0 后从源字符串追加num个字符到目标空间
  • 如果源字符串长度大于 num,则追加相应个数,追加后主动放 \0
  • 如果源字符串的长度小于 num,则拷贝完源字符串之后,不在目标的后边追加0,直接结束(与 strncpy 不同)

strncat模拟实现

char* my_strncat(char* dest, const char* src, size_t num) {
	assert(dest && src);
	char* ret = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++ = *src++) {
		num--;
		if (0 == num) {
			*dest++ = '\0';
			break;
		}
	}
	return ret;
}

strncmp

    int strncmp ( const char * str1, const char * str2, size_t num );
  • 从两个字符串起始地址开始,比较字符串中对应位置上字符的大小(ASCLL值),最多比较num个字符

strncmp模拟实现

int my_strncmp(const char* dest, const char* src, size_t num) {
	assert(dest && src);
	int ret = 0;
	while (!(ret = *(unsigned char*)src - *(unsigned char*)dest) && *dest) {
		++src, ++dest;
		num--;
		if (0 == num) {
			break;
		}
	}
	return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值