【C语言库函数】各字符串函数的使用及模拟实现

 2024-01-21 05:03:18  阅读 0

【C语言库函数】各字符串函数的使用及模拟实现

1. 1.1。 如何使用

这个功能大家一定都很熟悉了。 顾名思义,它的功能就是求字符串的长度。 使用时只需要传递一个字符串即可。 让我们在以下位置搜索这个函数:

你可以看看这个描述。 我们可以忽略下面一大堆英文描述。 我们看一下它的返回值类型,结果是——无符号整数。 这样的设计其实考虑到了字符串的长度必须大于零,但是这样的设计也会导致一种有些“奇怪”的情况:

这里它显然小于,但大于打印。 这是因为当进行两次计算时,最终的结果也必须是类型,即必须大于0。

所以关于这一点,我们在以后使用的时候需要特别注意。 如果我们想要将两个字符串的长度相减,最好强制将每个长度转换为int类型或者保存在int类型变量中。 例如:

1.2. 模拟实施

思路分析:

实现原理很简单,就是在遇到字符串结束标志'\0'之前统计字符串中的字符数,最后返回统计到的字符数。

模拟实现:

第一个是最简单的实现,计数器:

int my_strlen1(const char* str) {
	assert(str);
	int count = 0;
	while (*str++) {
		count++;
	}
	return count;
}

当我们了解了指针之后,我们知道指针减去指针就代表了指针之间的元素个数。 于是就有了第二种实现方法,指针减指针:

int my_strlen2(const char* str) {
	assert(str);
	const char* temp = str;
	while (*temp) {
		temp++;
	}
	return temp - str;
}

但有些问题可能要求你不要创建临时变量。 这时候就应该使用递归了,于是第三种实现方法,递归方法就出来了:

int my_strlen3(const char* str) {
	assert(str);
	if ('\0' == *str) {
		return 0;
	}
	else {
		return 1 + my_strlen3(str + 1);
	}
}

2.和2.1。 如何使用

作用是将一个字符串的内容(包括末尾的'\0')复制到另一个字符串中。 其次,还有n个以上。 这个n代表要复制的字符数。 。 例如我们现在有两个字符串:

char str1[] = "overtime!";
char str2[] = "no overtime!";

如果我们想将 str1 复制到 str2,我们可以使用:

如果我们想要复制str1的所有内容,但只想复制前4个字符,那么我们可以使用:

2.2. 模拟实施

在模拟之前,我们先看一下这两个函数的描述信息:

红线表示两个函数是否复制'\0'。 其中,strcp无论如何都会复制'\0',但只有当源字符串的长度小于要复制的字符数时,才会在末尾追加'\0',直到到达复制的字符为止。 直到数字等于num。

模拟实现:

:

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

:

char* my_strncpy(char* dest, const char* src, int num) {
	assert(dest && src);
	char* start = dest;
	while (num-- && (*dest++ = *src++)) {
		;
	}
	if (0 == num) {
		;
	}
	else {
		while (num-- > 0) {
			*dest++ = '\0';
		}
	}
	return start;
}

3.和3.1。 如何使用

作用是在一个字符串后面附加(连接)另一个字符串,和上面一样,意思是只连接几个字符,而不是整个字符串。

例如,我们现在有这两个字符串:

char str1[20] = "Salary";
char str2[] = " increase!!";

我们可以使用 str2 连接 str1:

我们还可以使用以下方法仅附加一个字符:

3.2. 模拟实施

在模拟实现之前,我们先看一下这两个函数的说明:

从描述中我们可以知道,两个函数在追加结束时都会添加一个字符串结束标志'\0',并且最多只会追加到原字符串的末尾。

事实上,当我们找到目标字符串的第一个'\0'时,我们只需要重复操作即可,但是要注意最多追加到原字符串的末尾。

模拟实现:

:

char* my_strcat(char* dest, const char* src) {
	assert(dest && src);
	char* start = dest;
	// 先找到的dest的第一个'\0'
	while (*dest) {
		dest++;
	}
	// 然后重复strcpy的操作即可
	while (*dest++ = *src++) {
		;
	}
	return start;
}

:

char* my_strncat(char* dest, const char* src, int num) {
	assert(dest && src);
	char* start = dest;
	// 先找到的dest的第一个'\0'
	while (*dest) {
		dest++;
	}
	// 然后重复strncpy的操作即可
	while (num-- && (*dest++ = *src++)) {
		;
	}
	dest = '\0'; // 只追加到src的结尾
	return start;
}

4.和4.1。 用法

功能是比较两个字符串的大小。 如果两个字符串相等,则返回0,否则返回其他数字。 比较方法是逐个字母进行比较。 如果当前比较的两个字母相等,则跳转到下一个字母。 如果它们不相等,则直接返回大于零或小于零的数字。

它将比较两个字符串的末尾,但最多只比较 n 个字符。

例如,我们现在有两个字符串:

char str1[] = "str";
char str2[] = "string";

我们可以通过以下方式比较这两个字符串是否相等:

它还可以用于仅比较它们的前三个字符,看看它们是否相同:

4.2. 模拟实施

两个函数的返回值应满足下表:

而我们知道字符的本质是一个ASCII码值,所以当我们找到两个不相等的字符后,我们可以直接返回它们的差值。

这两个函数的模拟方法其实很简单。 我这里直接编码:

模拟实现:

:

int my_strcmp(const char* str1, const char* str2) {
	assert(str1 && str2);
	while ((*str1 == *str2) && (*str1 && *str2)) {
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

:

int my_strncmp(const char* str1, const char* str2, int num) {
	assert(str1 && str2);
	int i = 0;
	for (i = 0; i < num; i++) {
		if (*(str1 + i) != *(str2 + i)) {
			return *(str1 + i) - *(str2 + i);
		}
	}
	return *(str1 + i - 1) - *(str2 + i - 1);
}

5. 5.1. 如何使用

作用是判断一个字符串是否是另一个字符串的字符串。 如果是,则返回指向子字符串出现的第一个位置的指针。 比如“ab”就是“aab”的字符串,他们两个传入返回的应该是指向“aab”中第二个a的指针。 如果不是,则返回空指针。

例如,我们现在有两个字符串:

char str1[] = "bab";
char str2[] = "aaababbbb";

我们可以用它来确定 str1 是否是 str2 的子字符串:

我们可以看到它返回的应该是一个指向第四个字符b的指针。

5.2. 模拟实施

虽然子串匹配的算法有很多,但今天我向大家介绍一种最简单的方法——朴素法:

char* my_strstr(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* temp = str1; // 在外层遍历str1,找到有一个*str2就停下
	const char* s1 = NULL; // 当temp找到一个*str2之后s1继续遍历temp后面的字符,判断子串
	const char* s2 = NULL; // 当temp找到一个*str2之后s2继续遍历str2后面的字符,判断子串
	while (*temp) {
		while ((*temp != *str2) && *temp) {
			temp++;
		}
		s1 = temp;
		s2 = str2;
		while ((*s1 == *s2) && (*s1 && *s2)) {
			s1++;
			s2++;
		}
		if ('\0' == *s2) {
			return (char*)temp;
		}
		else {
			temp++;
		}
	}
	return NULL;
}

标签: 字符 指针 拷贝

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码