【C语言】模拟实现字符串库函数

本篇文章目录

  • 相关文章
  • 1. strlen 求字符串长度
  • 2. 长度不受限制的字符串函数
    • 2.1 strcpy 字符串拷贝
    • 2.2 strcmp 字符串比较
    • 2.3 strcat 字符串连接
  • 3.strstr 字符串查找
  • 4. 长度受限的字符串函数
    • 4.1 strncpy
    • 4.2 strncat
    • 4.3 strncmp

相关文章

  1. 【C语言】善用const修饰指针变量,提高程序的健壮性!
  2. 【C语言】在这些情况下使用assert,比if语句强太多!
  3. 【C语言】指针与指针变量、内存的概念(6.2 指针-指针)

1. strlen 求字符串长度

不计算字符’\0’的长度。
比如"abcd\0efg"的长度只有4,因为strlen只计算\0之前的字符。

#include 
#include 
// 1.计数器方式
int my_strlen1(const char* str) {
	assert(str);
	int cnt = 0;
	while (*str++) {
		cnt++;
	}
	return cnt;
}
// 2.指针-指针方式
int my_strlen2(const char* str) {
	assert(str);
	char* start = str;
	while (*str != '\0') {
		str++;
	}
	return str - start;
}
// 3.递归方式
int my_strlen3(const char* str) {
	assert(str);
	if (*str) {
		return my_strlen3(str + 1) + 1;
	}
	return 0;
}
int main() {
	char str[] = "hello";
	printf("%d\n", my_strlen1(str));
	printf("%d\n", my_strlen2(str));
	printf("%d\n", my_strlen3(str));
	return 0;
}

2. 长度不受限制的字符串函数

2.1 strcpy 字符串拷贝

dest目标空间一定要足够大,能装下src的所有内容。
从dest起始位置开始复制所有src的内容。

#include 
#include 
char* my_strcpy1(char* dest, const char* src) {
	assert(dest && src);
	char* start = dest;
	while (*src) {
		*dest++ = *src++;
	}
	*dest = *src; // '\0'
	return start;
}
char* my_strcpy2(char* dest, const char* src) {
	assert(dest && src);
	char* start = dest;
	// 顺便一起拷贝'\0'
	while (*dest++ = *src++) {
		;
	}
	return start;
}
int main() {
	char src[] = "hello";
	char dest[] = "xxxxxxxxxxxxxxx";
	printf("%s\n", my_strcpy1(dest, src));
	return 0;
}

2.2 strcmp 字符串比较

挨个字符进行比较ASCII码值。
当str1大于str2时,返回大于0的数;
当str1小于str2时,返回小于0的数;
当str1等于str2时,返回0。
比如"abc"和"abd"进行比较,返回-1。

#include 
#include 
int my_strcmp(const char* str1, const char* str2) {
	assert(str1 && str2);
	while (*str1 && *str2 && *str1 == *str2) {
		str1++;
		str2++;
	}
	if (*str1 > *str2) {
		return 1;
	}
	else if (*str1 < *str2) {
		return -1;
	}
	else {
		return 0;
	}
}
int main() {
	char str1[] = "";
	char str2[] = "abc";
	printf("%d", my_strcmp(str1, str2));
	return 0;
}

2.3 strcat 字符串连接

dest空间需要足够大,能装下dest和src两个数组的内容。
从dest的\0位置开始复制src的内容,复制结束时加上\0,将dest和src内容连在一起。

#include 
#include 
char* my_strcat1(char* dest, const char* src) {
	assert(dest && src);
	char* destStart = dest;
	// 找到'\0'位置
	while (*dest) {
		dest++;
	}
	while (*src) {
		*dest++ = *src++;
	}
	*dest = *src; // 追加'\0'
	return destStart;
}
char* my_strcat2(char* dest, const char* src) {
	assert(dest && src);
	char* destStart = dest;
	// 找到'\0'位置
	while (*dest) {
		dest++;
	}
	while (*dest++ = *src++) {
		;
	}
	return destStart;
}
int main() {
	char dest[20] = "abcdefg";
	char src[] = "abz";
	printf("%s", my_strcat1(dest, src));
	return 0;
}

3.strstr 字符串查找

从字符串中查找子串,如果存在则返回从子串开始位置的字符串。
如从abbbcdef中查找bbc,返回bbcdef。

#include 
#include 
const char* my_strstr1(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* cp = str1;
	while (*cp) {
		char* s1 = cp;
		char* s2 = str2;
		while (*s1 && *s2 && *s1 == *s2) {
			s1++;
			s2++;
		}
		if (*s2 == '\0') {
			return cp;
		}
		cp++;
	}
	return NULL;
}
// 或计数器方式
const char* my_strstr2(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* cp = str1;
	while (*cp) {
		const char* s1 = cp;
		const char* s2 = str2;
		unsigned int cnt = 0;
		while (*s1 && *s2 && *s1++ == *s2++) {
			cnt++;
		}
		if (cnt == my_strlen(str2)) {
			return cp;
		}
		cp++;
	}
	return NULL;
}
int main() {
	char str1[] = "bbbcaba";
	char str2[] = "bbc";
	printf("%s", my_strstr1(str1, str2));
	return 0;
}

4. 长度受限的字符串函数

4.1 strncpy

从src中拷贝num个字符到dest;
如果src的长度不足num个,则在拷贝完src后,在dest后拷贝’\0’。
如下面程序中,拷贝完hello后,再追加3个’\0’。

#include 
#include 
char* my_strncpy(char* dest, const char* src, size_t num) {
	assert(dest && src);
	char* t = dest;
	while (num--) {
		if (*src) {
			*dest++ = *src++;
		}
		else {
			*dest++ = '\0';
		}
	}
	return t;
}
int main() {
	char dest[] = "xxxxxxxxxxxxxxx";
	char src[] = "hello";
	printf("%s", my_strncpy(dest, src, 8));
	return 0;
}

4.2 strncat

从dest中第1个\0位置开始,从src中连接num个字符,最后在dest后面追加一个\0;
如果src字符长度小于num,则只连接src中的所有内容,在dest追加一个\0。

#include 
#include 
#include 
const char* my_strncat(char* dest, const char* src, size_t num) {
	assert(dest && src);
	const char* t = dest;
	if (num > 0) {
		// dest指向‘\0'位置
		dest += strlen(dest);
		while (num-- && *src) {
			*dest++ = *src++;
		}
		*dest = '\0';
	}
	return t;
}
int main() {
	char dest[20] = "xxxx\0xxxx";
	char src[] = "abcd";
	printf("%s", strncat(dest, src, 6));
	return 0;
}

4.3 strncmp

指定比较num个字符。
或者当str1或str2字符长度小于num,则最多比较到\0。

#include 
#include 
int my_strncmp(const char* str1, const char* str2, size_t num) {
	assert(str1 && str2);
	while (num-- > 1 && *str1 && *str2 && *str1 == *str2) {
		str1++;
		str2++;
	}
	if (*str1 > *str2) {
		return 1;
	}
	else if (*str1 < *str2) {
		return -1;
	}
	else
	{
		return 0;
	}
}
int main() {
	char dest[] = "abd\0xxxx";
	char src[] = "abce";
	printf("%d", my_strncmp(dest, src, 2));
	return 0;
}

你可能感兴趣的:(C语言,c语言)