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


    相关文章

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    布尔盲注(原因找不到报错和联合)
    Qt源码分析--QObject(4)
    Aspose.Words for .NET查找和替换教程——如何查找和突出显示文本
    算法链表-局部反转
    主动写入流对@ResponseBody注解的影响 | 京东云技术团队
    内存错误分析工具----asan(AddressSanitizer)的介绍和使用
    计算机毕业设计之java+springboot基于vue的网上图书商城系统
    C++ 循环解析
    JSON从入门到大师
    Effective C++条款19:设计class犹如设计type(Treat class design as type design)
  • 原文地址:https://blog.csdn.net/m0_52602233/article/details/133127451