【从0到1|c语言进阶篇(字符串函数及模拟实现)


目录

  • 前言
  • 一、字符串函数是什么?
  • 二、字符串函数包括哪些、如何模拟实现
    • 1.字符串拷贝函数
      • (1)strncpy
      • (2)strcpy
    • 2.字符串追加函数
      • (1)strncat
      • (2)strcat
    • 3.字符串大小比较函数
      • (1)strncmp
      • (2)strcmp
    • 4.求字符串长度函数
      • (1)strlen函数注意事项
      • (2)strlen函数的三种实现方法
    • 5.字符串查找函数
    • 6.切割字符串函数
    • 7.把错误码转换成错误信息函数

前言 C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数。
一、字符串函数是什么?
字符串函数(String processing function)也叫字符串处理函数,指的是编程语言中用来进行字符串处理的函数。
二、字符串函数包括哪些、如何模拟实现 长度不受限制的字符串函数:
strcpy、strcat、strcmp
长度受限制的字符串函数:
strncpy、strncat、strncmp
字符串查找:
strstr
切割字符串:
strtok
错误信息报告:
strerror
1.字符串拷贝函数 (1)strncpy
strncpy函数的注意事项
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完原字符串之后,在目标的后边追加0,直到num个。
strncpy函数的模拟实现
char * strncpy(char * destination,const char * source,size_t num);

#include #includechar* my_strncpy(char* str1, const char* str2, int nums) { assert(str1 && str2); char* ret = str1; while (nums)//把str2拷贝到str1,剩余\0没拷贝 { *str1++ = *str2++; nums--; } if (nums > 0) { while (--nums)//拷贝/0 { *str1++ = '\0'; } } return ret; } int main() { char arr1[20] = "############"; char arr2[] = "Hello World!"; my_strncpy(arr1, arr2, 7); printf("%s\n", arr1); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

(2)strcpy
strcpy函数注意事项
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。 学会模拟实现。
strcpy函数的模拟实现
char * strcpy(char * destination,const char * source);

#includechar* my_strcpy(char* str1, const char* str2) { char* ret = str1; //先把目标的起始地址存放在ret里。 while (*str1++ = *str2++) { ; } return ret; //返回的是起始地址 } int main() { char arr1[20] = "################"; char arr2[] = "Hello World!"; my_strcpy(arr1, arr2); printf("%s\n", arr1); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

2.字符串追加函数 (1)strncat
strncat函数注意事项
追加num个字符从源字符串到目标空间
如果源字符串的长度小于num,追加完之后也会把\0追加过去,但如果字符不够不会补齐\0
strncat函数模拟实现
char * strncat(char * destination,const char * source,size_t num);

#include #includechar* my_strncat(char* str1, const char* str2, int num) { char* ret = str1; assert(str1 && str2); while (*str1) { str1++; } while (num--) { if ((*str1++ = *str2++) == 0) { return ret; } } *str1 = '\0'; return ret; } int main() { char arr1[20] = "Hello"; char arr2[] = "World!"; my_strncat(arr1, arr2, 3); printf("%s\n", arr1); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

(2)strcat
strcat函数的注意事项
源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
strcat函数的模拟实现
char * strcat(char * destination,const char * source);

#include#include char* my_strcat(char* dest, const char* src) { char* ret = dest; //找到目标字符串\0 assert(dest && src); while (*dest) { dest++; } //追加源字符串 while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[20] = "Hello "; char arr2[] = "World!"; my_strcat(arr1, arr2); printf("%s\n", arr1); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

3.字符串大小比较函数 (1)strncmp
strncmp函数注意事项
比较到出现另一个字符不一样或者一个字符串结束或者num个字符全部比较完
strncmp函数模拟实现
int strncmp ( const char * str1, const char * str2, size_t num );

#include #includeint my_strncmp(const char* str1, const char* str2, int n) { assert(str1 != NULL); assert(str2 != NULL); int ret = 0; while (!(ret = (*str1 - *str2)) && *str1 && (n--))//如果两者相等且不为'\0',并且只能比较字符串str1和str2的前maxlen个字符 { str1++; str2++; } if (ret < 0) ret = -1; else if (ret > 0) ret = 1; return ret; }int main() { char arr1[] = "abcdef"; char arr2[] = "abc"; int ret = my_strncmp(arr1, arr2, 5); printf("%d\n", ret); if (ret == 0) { printf("==\n"); } else if (ret < 0) { printf("<\n"); } else { printf(">\n"); } return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

(2)strcmp
strcmp函数注意事项
第一个字符串大于第二个字符串,
则返回大于0的数字 第一个字符串等于第二个字符串,
则返回0 第一个字符串小于第二个字符串,则返回小于0的数字
strcmp函数的模拟实现
int strcmp ( const char * str1, const char * str2);

#include#include int my_strcmp(const char* str1, const char* str2) { while (*str1 == *str2) { if (*str1 == '\0') { return 0; } str1++; str2++; } if (*str1 > *str2) { return 1; } else { return -1; } } int main() { char* p = "abcdef"; char* q = "abcdfe"; int ret = my_strcmp(p, q); if (ret == 0) { printf("==\n"); } else if (ret < 0) { printf("<\n"); } else { printf(">\n"); } return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

4.求字符串长度函数 (1)strlen函数注意事项
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包 含 ‘\0’ )。参数指向的字符串必须要以 ‘\0’ 结束。 注意函数的返回值为size_t,是无符号的( 易错 )
(2)strlen函数的三种实现方法
int strlen(const char* str)

方法一:
#include //我们初衷是求字符串的长度,不会改变字符串,所以加上const使指针指向的内容不会改变,更加安全 int my_strlen(const char* str)//1.计数器方法模拟实现strlen函数 { int counst = 0; //计数器 assert(str != NULL); //等价写法:assert(str) //对指针解引用一定得是个有效的指针,所以需要断言str不为空指针,下面解引用的话就会更加安全 while (*str != '\0')//等价写法:while(*str) { counst++; str++; } return counst; } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

方法二:
#includeint my_strlen(const char* str)//递归的方法模拟实现strlen函数 { if (*str != '\0') { return(1 + my_strlen(str + 1)); } else { return 0; } } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

方法三:
#includeint my_strlen(const char* str)//指针减指针的方法模拟实现strlen函数 { const char* start = str; const char* end = str; while (*end) { end++; } return end - start; } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

5.字符串查找函数 strstr函数注意事项
返回一个指针中str2在str1第一次出现的位置
strstr函数的模拟实现
char* strstr(const char* str1, const char* str2 )

#include #includechar* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); const char* s1 = NULL; const char* s2 = NULL; char* ret = str1; while (*ret) { s1 = ret; s2 = str2; while (*s1 && *s2 && (*s1 == *s2)) {s1++; s2++; if (*s2 == '\0') { return ret; } } ret++; } return NULL; } int main() { char arr1[20] = "abbbcdef"; char arr2[] = "bbc"; char* ret = my_strstr(arr1, arr2); if (ret != NULL) { printf("找到了:>%s\n", ret); } else { printf("查找的字符串找不到\n"); } return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

6.切割字符串函数 strtok函数注意事项
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。 strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。 如果字符串中不存在更多的标记,则返回 NULL 指针。
strtok函数的实现
#include #include int main() { const char* sep = "@."; char email[] = "moyuwangpangdudu@qq.com"; char cp[30] = { 0 }; strcpy(cp, email); char*ret = strtok(cp, sep); printf("%s\n", ret); ret = strtok(NULL, sep); printf("%s\n", ret); ret = strtok(NULL, sep); printf("%s\n", ret); return 0; }

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

7.把错误码转换成错误信息函数 strerror函数的注意事项
返回错误码,所对应的错误信息。
strerror函数的实现
char * strerror(int errnum);

#include #include #include //int errno; //全局错误码,存放错误信息的变量 int main() { FILE* pf = fopen("test.txt", "r"); //打开文件失败返回NULL if (pf == NULL) { printf("%s\n", strerror(errno)); } return 0; }

【【从0到1|c语言进阶篇(字符串函数及模拟实现)】【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

【从0到1|c语言进阶篇(字符串函数及模拟实现)
文章图片

    推荐阅读