目录
一、前言
二、字符串函数详解
1.求字符串长度:strlen()
2.字符串的拷贝:strcpy()
3.字符串连接函数:strcat()
4.字符串比较函数:strcmp()
5.长度不受限制的拷贝字符串函数: strncpy
6.长度不受限制的连接字符串函数: strncat
7. 长度不受限制的比较字符串函数: strncmp
8.字符串查找函数 strstr()
9.字符操作函数
三、共勉
再写字符串题目的时候,对于我这个小菜狗来说是一件非常难受的事情,经常会因为字符串的麻烦而导致我有想砸电脑的冲动,对此为了能够更好的理解字符串,我专门花了一天的时间去总结了字符串函数的应用与理解,希望对大家有帮助。
知识点1:
strlen()函数的头文件:#include
strlen()函数的声明:
如何应用:strlen()这个函数在求字符串长度时计算的是 ‘\0’ 之前的字符,且以 ‘\0’ 为字符串的结束标志。
代码举例(1): 字符串 "abcdfefeff " 长度为10
#include
#include
int main()
{
char a[50] = "abcdfefeff";
int len = strlen(a); // strlen()函数里放入字符串数组的首地址
printf("%d\n", len); //10
return 0;
}
代码举例(2):字符串 {'a','b','c','d'} 长度未知
#include
#include
int main()
{
char a[] = {'a','b','c','d'};
int len = strlen(a);
printf("%d\n", len); // 74
return 0;
}
此时结果显示为 74
原因解释:这里的结果是一个随机数,因为字符串里并没有 ‘\0’ 作为结束标志,所以它会继续往下数 。
知识点2:strlen() 函数的返回值 是无符号值
代码举例 :
#include
#include int main() { if(strlen("abc") - strlen("abcdef") > 0) { printf(">\n"); } else { printf("<\n"); } return 0; } 按照我们的常理判断 长度应该为 3-6=(-3)
但是streln()函数返回的是 无符号值 所以返回的(-3)就变成了 3
结果输出 : >
如果此时题目要求我们不能用strlen()函数,我们应该如何模拟呢?
代码演示strlen()函数模拟:
方法一:指针-指针
// 方法:指针-指针 #include
#include #include int my_strlen(const char *a) // size_t 返回指针 { assert(a); const char* star = a; const char* end = a; while (*end != '\0') { end++; } return end - star; } int main() { char a[] = "abcdef"; int len = my_strlen(a); printf("%d\n", len); return 0; } 方法二:计数器版本
#include
#include size_t my_strlen(const char* str) // const 保证字符串不再改变 { // size_t 保证返回的是一个无符号数 assert(str != NULL); //直接引用指针不安全,需要保证指针一定有效 int count = 0; while (*str++) count++; return count; } int main() { char arr[] = "abc"; printf("%d\n", my_strlen(arr)); return 0; }
知识点3:streln() 函数与 sizeof()函数的区别
1、 strlen 是函数,sizeof 是运算符。
2、strlen 测量的是字符的实际长度,以'\0' 结束。而sizeof 测量的是字符的分配大小。
代码举例:
char str[20] = "hello"; printf("strlen: %d\n", strlen(str)); // 5 printf("sizeof: %d\n", sizeof(str)); // 20
3、sizeof():返回所占总空间的字节数
(1)、对于整型字符型数组
(2)、对于整型或字符型指针
4、strlen():返回字符数组或字符串所占的字节数
(1)、针对字符数组
(2)、针对字符指针其中 sizeof() 可以巧妙的计算数组的长度代码如下所示:
#include
#include int main() { char a[] = {'a','b','c','d'}; int len = sizeof(a) / sizeof(a[0]); printf("%d\n", len); // 4 return 0; }
总结:
▶字符串以 ‘\0’ 作为结束标志,strlen函数的返回值是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
▶ 参数指向的字符必须要以 ‘\0’ 结束
▶ 注意函数的返回值为size_t,是无符号的(易错)▶ 注意strlen()函数与sizeof()函数的区别
知识点1:
strcpy()函数的头文件:#include
strcpy()函数的声明:
strcpy()函数应用:
strcpy会把源字符串中的内容拷贝到目标空间,并返回目标空间的起始位置
代码演示:
#include
int main() { char arr[20] = { 0 }; strcpy(arr, "hello"); printf("%s\n", arr); // hello return 0; }
知识点二:
模拟实现strcpy()函数:
#include
#include char * my_strcpy(char *dest,const char* str) //资源函数不能变,用const char *str { char* ret = dest; while (*str!='\0') { *dest = *str; dest++; str++; } return ret; } int main() { char arr[20] = "abc"; char arr1[] = "hello world"; my_strcpy(arr, arr1); printf("%s\n", arr); return 0; }
总结:
▶ 源字符串必须以 ‘\0’ 结束
▶ strcpy在拷贝的过程中是以 ‘\0’ 为结束标志,且会将 ‘\0’ 也拷贝
▶ 目标空间必须足够大,以确保能存放源字符串
▶ 目标空间必须可变(不能用 const 修饰)
知识点1:
strcat()函数的头文件:#includestrcat()函数的声明:
strcat()函数的应用: 源字符串在追加时会找到目标字符串最后的 ‘\0’ 并将它给覆盖,然后开始追加。
代码演示:
#include
int main() { char arr1[20] = "hello"; char arr2[] = "bit"; strcat(arr1, arr2); printf("%s\n", arr1); // hellobit return 0; } 大家是都有跟我一样的疑问,在源字符串给目标函数追加时,源字符串的 '\0' 会不会也会追加呢?我们来调试看一下。
代码如下:
#include
#include int main() { char a[20] = "hello \0 xxxxx"; //在末尾开始追加,用'\0',来判断末尾 char b[] = "world"; strcat(a, b); //字符串连接 printf("%s\n", a); // hello world return 0; } 从图中我们发现源字符串的 '\0' 也追加过来了
知识点2:
strcat()函数的模拟实现代码如下:
#include
#include char *my_strcat(char* dest, const char* str) { char* ret = dest; while (*dest != '\0') { dest++; } while (*str != '\0') { *dest = *str; dest++; str++; } return ret; } int main() { char a[20] = "hello xx"; char b[] = " world"; my_strcat(a, b); printf("%s\n", a); return 0; }
总结:
▶ 源字符串必须以 ‘\0’ 结束
▶ 目标空间必须足够大,以足以容纳字符串
▶ 目标字符串必须可修改
▶ 不能自己追加自己
知识点1:
strcmp()函数的头文件:#include
strcmp()函数的声明:
strcmp()函数的返回值:
strcat()函数的应用:
比较对应而位置上的字符的大小(通过指针比较),而非长度
如果出现一对 > 或者 < ,则停止比较,否则直到比较到 '\0' 为止就是相等输出 0 。
代码验证:
#include
#include int main() { char a[] = "abc"; char b[] = "abd"; int len = strcmp(a, b); printf("%d\n", len); // -1 return 0; }
知识点2:
strcmp()函数的模拟实现:
#include
#include #include int my_strcmp(const char* s1, const char* s2) { assert(s1 && s2); // 保证两个指针不是空指针 while (*s1 == *s2) { if (*s1 == '\0') { return 0; } s1++; s2++; } if (*s1 > *s2) { return 1; } else { return -1; } } int main() { char a[] = "abc"; char b[] = "abc"; int len = my_strcmp(a, b); printf("%d\n", len); // 0 return 0; }
知识点1:
strncpy()函数的头文件:#include
strncpy()函数的声明:
strncpy()函数的应用:可以根据自己的想法或者题目的要求去拷贝需要的字符个数,不需要将字符串全部拷贝完。
代码演示:
#include
#include int main() { char a[20] = "abcdef"; char b[] = "xxxx"; strncpy(a, b, 2); // 拷贝两个字符到目标空间 printf("%s\n", a); // xxcdef return 0; } 大家可以考虑一个问题,当指定的拷贝个数大于源字符串的个数会出现怎样的情况呢?
代码演示:
#include
#include int main() { char a[20] = "abcdef"; char b[] = "xxxx"; strncpy(a, b, 8); printf("%s\n", a); // xxxx 多出来的后面补上 '\0' return 0; } 我们发现,多出来的个数,会按 '\0' 进行补充
知识点2:
模拟实现strncpy()函数#include
#include char* my_strncpy(char* dest, const char* str, size_t num) { char* ret = dest; int len = strlen(str); int k = num - len; if (num > len) { while (len--) { *dest = *str; dest++; str++; } // 超出的部分补上 '\0' while (k--) { *dest = '\0'; dest++; } } else { while (num--) { *dest = *str; dest++; str++; } } return ret; } int main() { char a[20] = "abcdef"; char b[] = "xxxx"; my_strncpy(a, b, 2); printf("%s\n", a); return 0; }
总结:
▶ 拷贝num个字符从源字符串到目标空间
▶ 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加0,直到num个
知识点1;
strncat()函数的头文件:#include
strncat()函数的声明:
strncat()函数的应用:可以根据自己的想法或者题目的要求去连接需要的字符个数,不需要将字符串全部连接完。
代码演示:
#include
#include int main() { char a[20] = "abcdef\0qqqq"; char b[] = "xxxx"; strncat(a, b, 2); // abcdefxx printf("%s\n", a); return 0; } 大家可以考虑一个问题,当指定的连接个数大于源字符串的个数会出现怎样的情况呢?
#include
#include int main() { char a[20] = "abcdef"; char b[] = "xxxx"; strncat(a, b, 8); // abcdefxxxx 后补上'\0' printf("%s\n", a); return 0; } 我们发现,多出来的个数,会按 '\0' 进行补充
知识点2:
此时的strnact()函数可以进行 自己连接自己#include
#include int main() { char a[20] = "abc"; strncat(a, a, 3); printf("%s\n", a); //abcabc return 0; }
知识点3:
模拟实现strncat()函数:
#include
#include char* My_strncat(char* dest, const char* source, size_t count) { assert(dest && source); char* ret = dest; // 保存初始地址,因为后面会改变初始地址 while(*dest != '\0') // 先找到 \0 然后等待追加 { dest++; } while(count) // 因为追加受限制于 count 所以 while 循环条件是 count { *dest = *source; dest++; source++; count--; } return ret; // 返回初始地址 } int main() { char arr1[20] = "Hello"; char arr2[] = " world"; // char* ret = My_strncat(arr1, arr2, 6); // 创建指针变量接收打印 // printf("%s\n", ret); printf("%s\n", My_strncat(arr1, arr2, 6)); // 链式访问,也可以创建指针变量接收打印 return 0; }
知识点1:
strncmp()函数的头文件:#includestrncmp()函数的声明:
strncmp()函数的应用:可以根据自己的想法或者题目的要求去比较需要的字符个数,不需要将字符串全部比较完。
代码演示:
#include
#include int main() { int ret = strncmp("abcdef", "abc",3); // 相等为0 printf("%d\n", ret); return 0; }
知识点2:
模拟实现strncmp()函数
#include
#include int My_strncmp( const char *str1, const char *str2, size_t count ) { assert(str1 && str2); while(count--) // count 做条件 { if(*str1 == *str2) // 判断是否相等 { if( (*str1 == '\0') || (count == 0) ) // 如果是 '\0' 或者 count = 0 返回 { return 0; } str1++; str2++; } // 不相等 可以用 if 语句,但是 strncmp 返回的是 >0 <0 =0 而不是 1 -1 所以严谨一点直接解引用 相减 // if(*str1 > *str2) // { // return 1; // } // if(*str1 <*str2) // { // return -1; // } // } return *str1 - *str2; // 做差 是 字符的 ASCII 码大小 } int main() { char arr1[] = "abcdea"; char arr2[] = "abcdez"; int ret = My_strncmp(arr1, arr2, 6); // 创建整型接受返回值 if(ret > 0) { printf(">\n"); } else if(ret < 0) { printf("<\n"); } else { printf("=\n"); } printf("%d\n", ret); return 0; }
知识点1:
strstr()函数的头文件:#include
strstr()函数的声明:
strstr()函数的应用:
在一个字符串中找另一一个字符串是否存在
存在:返回的字符串所在的起始地址(第一次出现得到地址)
不存在:返回空指针--NULL
存在 :返回字符串第一次出现的位置代码演示:
#include
#include int main() { char a[] = "abcdef"; char b[] = "bcd"; char* p = strstr(a, b); if (p == NULL) { printf("不存在"); } else { printf("%s\n", p); //bcdef } return 0; }
*******重点:知识点2:
用于多次匹配直到母串结束记录,统计子串在母串中出现的次数
#include
#include int main() { int i,n,j,k=0; char a1[1001],a2[1001]; scanf("%s %s",a1,a2); char *p; p=a1; while( ( p=strstr(p,a2) ) != NULL)//p为子串与母串匹配成功 { //时,子串第一个符号在母串 k++; //中出现的位置地址 p++; //p++后才能匹配下一个,否则无法退出循环 } printf("%d",k); }
结果:
abababababa
aba
5
知识点3:
模拟实现strstr()函数#include
#include char* my_strstr(const char* str1, const char* str2) { const char* s1 = str1; const char* s2 = str2; const char* p = str1; if (*str2 == '\0') { return (char *)str1; } while (*p != '\0') { s1 = p; s2 = str2; while (*s1!='\0'&&*s2!='\0'&& * s1 == *s2) { s1++; s2++; } if (*s2 == '\0') { return (char *)p; //找到了 } p++; } return NULL; //找不到子串 } int main() { char a[] = "abcdef"; char b[] = "abc"; char* p = my_strstr(a, b); if (p == NULL) { printf("不存在\n"); } else { printf("%s\n", p); } return 0; }
知识点1:
字符分类函数:
这些函数的头文件:#include
在这里我给大家简单介绍几个常用的,大家可以跟着照猫画虎。
知识点2:
函数isdigit() :判断是不是数字
isdigit()函数的声明:
代码演示:
#include
#include int main() { char ch = '@'; //如果是数字字符返回非0的值,否则返回0 int ret = isdigit(ch); printf("%d\n", ret); return 0; }
以下就是我对C语言常用字符串函数的初阶理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C语言常用字符串函数的进阶理解,请持续关注我哦!!!!!