博客主页:PH_modest的博客主页
当前专栏:C语言跬步积累
其他专栏:
每日一题
读书笔记
每日反刍
座右铭:广积粮,缓称王!

一.strlen(计算字符串的长度)

1.知识点

1.strlen函数返回值类型是size_t(无符号整型);
请看下面代码输出的是什么:

#include#includeint main(){if (strlen("abc") - strlen("abcdef") > 0){printf(">\n");}else    {printf("<=\n");}return 0;}

很多人可能觉得输出结果是<,他们认为结果是-3,所以是<;
但其实结果不然

原因很简单,就是因为strlen的返回值是无符号整型,无符号数-无符号数结果还是无符号数,无符号数是没有负号的,恒大于0

2.字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’ )

3.参数指向的字符串必须要以 ‘\0’ 结束,否则返回值将会是一个随机值

2.strlen的模拟

方法一:计数器

#includeint my_strlen(char* arr){int flag = 0;while(*arr != '\0'){flag++;arr++;}return flag;}int main(){char arr[] = "abcde";int ret = 0;ret = my_strlen(arr);printf("%d\n", ret);return 0;}

方法二:递归

#include#includeint my_strlen(const char* arr){assert(arr);//断言,判断一下arr是否是空指针,使代码更加安全if (*arr != '\0'){return 1 + my_strlen(arr + 1);}else{return 0;}}int main(){char arr[] = "abcde";int ret = 0;ret = my_strlen(arr);printf("%d\n", ret);return 0;}

二.strcpy(将一个字符串内的内容复制到另一个字符串中)

1.知识点

  • 源字符串必须以’\0’结束;
  • 会将源字符串中的’\0’拷贝到目标空间;
  • 目标空间必须足够大,才能确保能存放源字符串;
  • 目标空间必须可修改;(即不能用const进行修饰

为了方便大家理解,请判断以下代码有何问题?

代码1:

#include#includeint main(){char* p = "abcdef";char arr[10]="ghi";strcpy(p,arr);printf("%s\n",p);return 0;}

该代码是错误的,p的类型是char*,这是一个指向字符串常量的指针,指向的内容是不可修改的

2.strcpy的模拟

#include#includechar* my_strcpy(char* arr2, const char* arr1){char* ret = arr2;//返回的是目标空间的起始地址,所以需要保存起始地址assert(arr1 && arr2);while(*arr1 != '\0'){*arr2 = *arr1;arr1++;arr2++;}*arr2 = *arr1;return ret;//返回起始地址}int main(){char arr1[10] = "hehe!";char arr2[20] = "0";char ret = "0";ret = my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;}

三.strcat(将一个字符串的内容追加到另一个字符串后面)

1.知识点

  • 源字符串必须以’\0’结束;
  • 目标空间必须有足够大的、能容纳下源字符串的内容;
  • 目标空间必须可修改;
  • 字符串不能给自己追加

2.strcat的模拟

#include#includechar* my_strcat(char* arr1, const char* arr2){char* ret = arr1;//将首地址赋给ret,便于最后返回字符串的首地址assert(arr1 && arr2);char* pc = arr1;while (*pc != '\0')//找到目标空间的'\0'{pc++;}while (*pc++ = *arr2++)//拷贝{;}return ret;}int main(){char arr1[20] = "hello ";char arr2[10] = "bit!";my_strcat(arr1, arr2);printf("%s\n",arr1);return 0;}

四.strcmp(比较两个字符串的大小)

1.知识点

标准规定:

  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

注意: strcmp返回值并非是和0,1比较的,但有些编译器可能大于时返回1,小于时返回-1,等于时返回0,这点需要注意一下,在之后判断时最好和0比较,即判断返回值是大于0,还是小于0,还是等于0

2. strcmp的模拟

#include#includeint my_strcmp(const char* arr1, const char* arr2){assert(arr1 && arr2);while (*arr1 == *arr2){if (*arr1 == '\0'){return 0;}arr1++;arr2++;}return (*arr1 - *arr2);}int main(){char arr1[20] = "abceef";char arr2[20] = "abceaf";int ret = 0;ret = my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;}

五.strstr(寻找一个字符串中是否存在另一个字符串)

1.知识点

  • 如果能找到,返回找到的字符串的首地址
  • 如果没找到,返回空指针(NULL)

2.strstr的模拟

#include#includechar* my_strstr(const char* arr1, const char* arr2){assert(arr1 && arr2);char* p1 = (char*)arr1;//用来游历,比较是否相等,不相等会返回char* p2 = (char*)arr2;char* str = (char*)arr1;//用来标记,便于返回while (*str){p1 = str;p2 = (char*)arr2;while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2){p1++;p2++;}if (*p2 == '\0'){return str;}else{str++;}}return NULL;}int main(){char arr1[20] = "abbcdefg";char arr2[20] = "bcd";char* ret = NULL;ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);}return 0;}

初始图:

结束图:

最后:

本篇博客粗略的介绍了一下部分字符串函数,这些字符串函数都是长度不受限制的,还有部分长度受限制的字符串函数将在本专栏下一篇中讲解,感兴趣的欢迎订阅本专栏。