字符串函数详解❤包括模拟实现

字符串函数的种类

我们总共会介绍以下几个字符串函数:
1.strlen(求字符串长度)
,2.strcpy(拷贝字符串)
,3.strcat(在目标内容末尾追加内容)
,4.strcmp(比较2个字符串)
,5,strncpy
,6.strncat
,7.strncmp
,8.strtok(切分字符串)
,9.strstr(在字符串中找子字符串)
,10.strerror(返回一个错误码所对应的错误信息字符串的起始地址)

1:strlen(求字符串长度)

strlen我们已经很熟悉了,
同时,我们可以自己模拟去实现strlen函数,以下,我提供了3种方法来实现:1,遍历,2,指针-指针,
3,递归。

//strlen的模拟实现
//方法1 遍历
size_t my_strlen(const char* str) {
	int count = 0;
	assert(str != NULL);
	while (*str != '\0') {
		count++;
		str++;
	}
	return count;
}
//方法2:指针-指针
size_t my_strlen2(const char* str) {
	assert(str);
	char* tmp = str;
	while (*str != '\0') {
		str++;
	}
	return str - tmp;
}
//方法3:递归
//不能使用临时变量
size_t my_strlen3(const char* str) {
	if (*str != '\0') {
		return 1 + my_strlen3(str + 1);
	}
	else {
		return 0;
	}
}
int main() {
	char arr[] = "abcdef";
	size_t len = my_strlen3(arr);
	printf("%zd", len);
	return 0;
}

2:strcpy(拷贝字符串)

我们经常使用它来拷贝字符串,但是有几个要注意的点:1:原字符串中必须包括’\0’,同时\0也会被拷贝。2:保证目标空间足够大,能够放的下要拷贝来的内容。3:保证目标空间可以修改。
同时我也提供了模拟实现的方法:如图所示:

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

}
int main() {
	char arr1[] = "hello,world";
	char arr2[] = "xxxxxxxxxxxxxxxxx";
	//将arr1的内容拷贝到arr2中
	//链式访问
	printf("%s", my_strcpy(arr2, arr1));

	return 0;
}

3:strcat(在目标内容末尾追加内容)

在使用strcat函数时候,也同样有要注意的点:1,目标空间得有\0,原空间也得有\0。2,目标空间足够大。3,目标可以修改。4,最好不用自己追加自己的内容,如果非要自己追加自己的内容,我们通常会使用strncat函数。
strcat的模拟实现如下:

char* my_strcat(char* dest, const char* src) {
	char* ret = dest;
	assert(dest && src);
	while (*dest != '\0') {
		dest++;
	}
	while (*src != '\0') {
		*dest++ = *src++;
	}
	return ret;
}
int main() {
	char arr1[] = "world!";
	char arr2[20] = "hello ";
	//把arr1的内容追加到arr2中
	//链式访问
	printf("%s", my_strcat(arr2,arr1));

	return 0;
}

4:strcmp(比较2个字符串)

strcmp用于比较两个字符串中对应位置上的字符,按字典序比较,比如有2个字符串
A:abcdef\0
B:abq\0
比较规则:如果2个字符串相等,则返回0;
如果A>B,则返回大于0的数;
如果A<B,则返回小于0的数。
模拟实现的代码如下:

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;
}

int main() {
	char arr[] = "abcde";
	char arr2[] = "abce";
	//int ret=strcmp(arr, arr2);
	int ret2 = my_strcmp(arr, arr2);
	//printf("%d", ret);
	printf("%d", ret2);

	return 0;
}

5:strncpy

strncpy同样是字符串拷贝函数,只不过比strcpy多了一个参数而已,多了一个长度的参数,size_t num;
用于控制要拷贝的字符数。
模拟实现如下:

char* my_strncpy( char* str1, const char* str2,size_t num) {
	assert(str1 && str2);
	char* ret = str1;
	int i = 0;
		while (*str2&&i<num) {
			*ret++ = *str2++;
			i++;//3
		}
		for (int j = i; j < num; j++) {
			*ret++ = 0;
		}
	return str1;
}
int main() {
	char arr1[20] = "abcedf";
	char arr2[] = "wor";
	my_strncpy(arr1, arr2, 3);//拷贝3个字符到arr1中
	printf("%s\n", arr1);

	return 0;
}

6:strncat

strncat也是追加函数,但是可以实现自己追加自己。
多了管理长度的参数。
模拟实现如下:

char* my_strncat(char* str1, const char* str2, size_t num) {
	assert(str1 && str2);
	char* ret = str1;
	//让str1指向\0,从\0开始追加
	while (*str1) {
		str1++;
	}
	int i = 0;
	while (*str2&&i<num) {
		*str1++ = *str2++;
		i++;
	}
	*str1 = 0;
	return ret;
}
int main() {
	char arr1[30] = "hello";
	char arr2[] = "world";
	//strncat(arr1, arr2, 5);
	char* ret = my_strncat(arr1, arr1, 3);
	printf("%s\n", ret);

	return 0;
}

7:strncmp

这个函数也字符串比较。比较简单,就不演示模拟实现了。

8:strstr(在字符串中找子字符串)

strstr在字符串中找一个子字符串,如果存在,则返回第一次出现的地址,如果不存在,则返回一个空指针。
模拟实现代码如下:

char* my_strstr(const char* str1,const char* str2) {
	assert(str1);
	assert(str2);
	const char* cp = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;

	while (*cp) {
		s1 = cp;
		s2 = str2;
		while (*s1 == *s2 && *s1 != '\0' && s2 != '\0') {
			s1++;
			s2++;
		}
		if (*s2 == '\0') {
			return cp;
		}
		cp++;
	}
	return NULL;
}
int main() {
	char arr1[] = "abbbcde";
	char arr2[] = "bbc";
	char* ret=my_strstr(arr1, arr2);
	if (ret != NULL) {
		printf("%s", ret);
	}
	else {
		printf("子集不存在!\n");
	}

	return 0;
}

9:strtok(切分字符串)

如果第一个参数为NULL;函数将在同一个字符串被保存的位置开始,查找下一个标记,只有第一次调用strtok才要传参,后面都可以直接传NULL,第一次调用完以后会保存目标位置。

10:strerror(返回错误码信息)

当库函数调用失败时候,会将错误码记录到errno这个变量中,errno是一个全局变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值