C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。本篇文章为大家详解八个常用的字符串操作函数,同时我们尝试模拟实现该函数,加深我们对函数的认识和了解。
目录
strlen(): 返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
函数原型
注:
需包含
头文件 字符串以 '\0' 作为结束标志。
参数指向的字符串必须要以 '\0' 结束。
注意函数的返回值为size_t,是无符号的(unsigned int)( 易错 )
- int main()
- {
- const char* p = "Hello world";
- int len = (int)strlen(p);
- printf("%d\n", len);
- return 0;
- }
创建临时变量
#include #include // 创建临时变量实现strlen int my_strlen(const char* str) { int count = 0; assert(str);//不为空指针 while (*str) { count++; str++; } return count; } int main() { const char* ch = "abcdef"; int len = my_strlen(ch); printf("%d\n", len);// 6 return 0; }不创建临时变量(递归实现)
// 不创建临时变量实现strlen int my_strlen(const char* str) { if (*str == '\0') { return 0; } else { return 1 + my_strlen(str + 1); } } int main() { const char* ch = "abcdef"; int len = my_strlen(ch); printf("%d\n", len);// 6 return 0; }
strcpy(): 将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)。
函数原型
注:Destination(目的地),Source(源自)
需包含
头文件 源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
- int main()
- {
- char ch1[20] = { 0 };
- const char ch2[] = "hello world";
- strcpy(ch1, ch2);
- printf("%s\n", ch1);
- return 0;
- }
- #include
- #include
- //模拟实现strcpy函数
- char* my_strcpy(char* des, const char* sou)
- {
- char* ret = des;
- assert(des && sou);//不为空指针
- // 拷贝
- while (*des++ = *sou++)
- {
- ;
- }
- return ret;//返回目标地址
- }
-
- int main()
- {
- char ch1[20] = { 0 };
- const char ch2[] = "hello world";
- my_strcpy(ch1, ch2);
- printf("%s\n", ch1); // hello world
- return 0;
- }
strcat(): 将源字符串的副本追加到目标字符串。目标中的终止空字符(\0)被源的第一个字符覆盖,并在目标中两者的连接形成的新字符串的末尾包含一个空字符(\0)。
函数原型
注:
需包含
头文件 源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改
不可自己追加追加
- int main()
- {
- char ch1[30] = "hello ";
- const char ch2[] = "world";
- strcat(ch1, ch2);
- printf("%s\n", ch1);
- return 0;
- }
- #include
- #include
- //模拟实现strcat
- char* my_strcat(char* des, const char* sou)
- {
- assert(des && sou);
- char* ret = des;
- //找到目标字符串的‘\0’
- while (*des)
- {
- des++;
- }
- //追加
- while (*des++ = *sou++)
- {
- ;
- }
- return ret;//返回目标地址
- }
- int main()
- {
- char ch1[30] = "hello ";
- const char ch2[] = "world";
- my_strcat(ch1, ch2);
- printf("%s\n", ch1);// hello world
- return 0;
- }
strcmp(): 比较每个字符串的第一个字符。如果它们相等,则继续执行以下对,直到字符不同或到达一个终止的空字符为止。
函数原型
返回值:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
注:比较大小的依据:不是比较两个字符串的长度,而是比较两个字符串中字符的ASCII码值大小
- int main()
- {
- const char* p1 = "abcdef";// a 的ASCII码为 97
- const char* p2 = "bcdef";// b 的ASCII码为 98
- int ret = strcmp(p1, p2);
- printf("%d\n", ret);
- return 0;
- }
- #include
- #include
- // 模拟实现strcmp
- int my_strcmp(const char* des, const char* sou)
- {
- assert(des && sou);
- //如果两个字符相等,继续往后面找到不同字符进行比较
- while (*des == *sou)
- {
- //元素全部相等
- if (*des == '\0')
- {
- return 0;
- }
- des++;
- sou++;
- }
- //返回值
- return *des - *sou;
- }
-
- int main()
- {
- const char* p1 = "abcdef";// a 的ASCII码为 97
- const char* p2 = "bcdef";// b 的ASCII码为 98
- int ret = my_strcmp(p1, p2);
- printf("%d\n", ret);
- return 0;
- }
strncpy():将源字符串的num个字符复制到目标。如果源字符串的结束在复制字符之前找到,目标将用0填充,直到总共向其写入了num字符 。
函数原型
注:
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
- int main()
- {
- char p1[20] = "abcd";
- const char p2[] = "hello";
- strncpy(p1, p2,2 );
- printf("%s\n", p1);
- return 0;
- }
- #include
- #include
- // 模拟实现strncpy
- char* my_strncpy(char* des, const char* sou, unsigned int num)
- {
- assert(des && sou);
- char* ret = des;
- //拷贝
- while (num && (*des++ = *sou++))//num范围
- {
- num--;
- }
- //范围大于源字符串全部置0
- if (num)
- {
- while (--num)//先--再使用,避免多进入循环一次
- {
- *des++ = '\0';
- }
- }
- return des;//返回目标值
- }
- int main()
- {
- char p1[20] = "abcd\0aaaaaaa";
- const char p2[] = "hello";
- my_strncpy(p1, p2, 8);
- printf("%s\n", p1);
- return 0;
- }
strncat(): 将源字符串的num个字符加上一个结束空字符追加到目标。如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容。
函数原型
注:
需包含
头文件 如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容。
- int main()
- {
- char p1[20] = "hello";
- const char p2[] = "world";
- strncat(p1, p2, 3);
- printf("%s\n", p1);
- return 0;
- }
- #include
- #include
- // 模拟实现strncat
- char* my_strncat(char* des, const char* sou, unsigned int num)
- {
- assert(des && sou);//不为空
- char* ret = des;
- //找到目标字符串的'\0'
- while (*des)
- {
- des++;
- }
- //按给定范围追加
- while (num && (*des = *sou))
- {
- num--;
- des++;
- sou++;
- }
- return ret;//返回目标地址
- }
-
- int main()
- {
- char ch1[20] = "hello\0aaaaaaa";
- char ch2[] = "world";
- my_strncat(ch1, ch2, 8);
- printf("%s\n", ch1);
- return 0;
- }
strncmp(): 比较到出现一个字符串结束或者num个字符全部比较完
函数原型
返回值
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字注:
比较是两个字符串一起比较相同num范围
比较的是两个字符串中字符的ASCII码值大小
- int main()
- {
- const char* p1 = "abcdef";
- const char* p2 = "bcde";
- int ret = strncmp(p1, p2, 2);//比较的是ab-bc
- printf("%d\n", ret);
- return 0;
- }
- #include
- #include
- int my_strncmp(const char* p1, const char* p2, unsigned int num)
- {
- assert(p1 && p2);//不为空
- //先找到不相同的字符
- while (num && (*p1 == *p2))
- {
- num--;
- p1++;
- p2++;
- }
- if (num == 0)//num个字符都相等
- return 0;
- else
- return *p1 - *p2;
- }
- int main()
- {
- const char* p1 = "dbcdef";
- const char* p2 = "dzde";
- int ret = my_strncmp(p1, p2, 2);//比较的是db-dz
- printf("%d\n", ret);// -24
- return 0;
- }
strstr(): 查找子字符串,返回指向目标字符串中需要查找到的第一个出现的指针,如果str2不是str1的一部分,则返回一个空指针
函数原型
注:
如果源字符串中出现多个需查找的子字符串,返回的是第一个出现的地址
- int main()
- {
- const char* p1 = "abcdefg";
- const char* p2 = "cd";
- char* ret = strstr(p1, p2);
- printf("%s\n", ret);
- return 0;
- }
- #include
- #include
- //模拟实现strstr
- char* my_strstr(const char* p1, const char* p2)
- {
- assert(p1 && p2);//不为空
- char* s1 = NULL;
- char* s2 = NULL;//使p1和p2发生改变
- char* cur = (char*)p1;//用来存放查找到地址
- if (*p2 == '\0')//查找子字符串只存放了'\0'
- {
- return (char*)p1;
- }
- //开始查找
- while (*cur)
- {
- s1 = cur;
- s2 = (char*)p2;
- //查找到一个相同的字符串,判断后面是不是全部相同,两个字符串不为\0,s1等于s2
- while (*s1 && *s2 && (*s1 == *s2))
- {
- s1++;
- s2++;
- }
- // 判断s1被查完既查找字符串长度大于源字符串abc-abcd
- if (*s1 == '\0')
- {
- return NULL;
- }
- //判断p2是否全部查找完了
- if (*s2 == '\0')
- {
- return cur;//返回第一次出现的地址
- }
- cur++;
- }
- return NULL;//源字符串查找完了没找到子字符串中的内容,返回空指针
- }
-
- int main()
- {
- const char* p1 = "abcdefg";
- const char* p2 = "cd";
- char* ret = my_strstr(p1, p2);
- printf("%s\n", ret);// cdefg
- return 0;
- }