目录
前言:
初学者在做与字符串相关的代码题时,善用字符串函数可能能让你的做题思路更加清晰,事半功倍,所以我们今天来介绍一些常见的字符串函数
(PS:在使用以下字符串函数时都需要包含头文件:#include <string.h>)
1. strlen 函数
函数介绍
size_t strlen ( const char * str );
功能:求字符串长度
- 该函数返回的是在字符串中 '\0' 前面出现的字符个数,但不包含 '\0'
- 参数指向的字符串必须要以 '\0' 结束,否则无法计算字符串长度
- 函数的返回值类型为 size_t,是无符号整数,因此结果一定是大于或等于 0
strlen 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[] = "abcdef";
size_t ret = strlen(ch1);
printf("%d\n", ret); // 6
return 0;
}
strlen 函数的模拟实现
模拟思路:因为 strlen 函数求字符串长度的原理是以 '\0' 为结束标志来计算字符个数,所以我们得根据这个性质来模拟实现它
方法一:逐个计数求字符个数
size_t mock_strlen(const char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
方法二: 两个指针相减求字符个数
size_t mock_strlen(const char* str)
{
int count = 0;
char* p = str;
while (*p != '\0')
p++;
return p - str;
}
2. strcpy 函数
函数介绍
char * strcpy ( char * destination, const char * source );
功能:拷贝字符串(把源字符串拷贝到目标字符串)
- 源字符串 source 必须以 '\0' 结束
- 目标字符串 destination 必须是可修改的,并且空间得足够大,以确保能存放源字符串
- 要注意函数参数的顺序,目标字符串在前,源字符串在后
strcpy 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[] = "abcd";
char ch2[20] = { 0 };
strcpy(ch2, ch1);
printf("%s\n", ch2); //abcd
return 0;
}
strcpy 函数的模拟实现
模拟思路: 创建一个空间足够大的字符数组,把每个字符一一拷贝过来,最后要记得把 '\0' 也拷贝过来
char* mock_strcpy(char* dest, const char* src)
{
// 创建一个临时指针记住目标字符串的起始位置
char* ret = dest;
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
return ret;
}
实际上我们还可以再简化这个代码:整合 while 判断和后置++
简化后的模拟函数:
char* mock_strcpy(char* dest, const char* src)
{
// 创建一个临时指针记住目标字符串的起始位置
char* ret = dest;
while (*(dest++) = *(src++))
{
;
}
return ret;
}
3. strcat 函数
函数介绍
char * strcat ( char * destination, const char * source );
功能:追加字符串(在一个字符串后追加另一个字符串)
- 源字符串 source,目标字符串 destination 都必须以 '\0' 结束
- 目标字符串 destination 必须是可修改的,并且空间得足够大,以确保能容纳下源字符串
- 要注意函数参数的顺序,目标字符串在前,源字符串在后
strcat 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[10] = "abc";
char ch2[] = "def";
strcat(ch1, ch2);
printf("%s\n", ch1); //abcdef
return 0;
}
strcat 函数的模拟实现
模拟思路:找到目标空间的 '\0' ,在后面把源字符串拷贝进去
char* mock_strcat(char* dest, const char* src)
{
char* ret = dest;
while (*dest)
{
dest++;
}
while (*(dest++) = *(src++))
{
;
}
return ret;
}
4. strcmp 函数
函数介绍
int strcmp ( const char * str1, const char * str2 );
功能:比较字符串 str1 和字符串 str2 的大小
- 如果第一个字符串大于第二个字符串,则返回大于 0 的数字
- 如果第一个字符串小于第二个字符串,则返回小于 0 的数字
- 如果第一个字符串等于第二个字符串,则返回 0
(PS:比较两个字符串大小的原理:比较的是两个字符串中对应位置上字符的ASCII码值的大小)
strcmp 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[] = "abcd";
char ch2[] = "abce";
// e的ASCII码值大于d的ASCII码值
int ret = strcmp(ch1, ch2);
if (ret > 0)
printf("大于\n");
else if (ret < 0)
printf("小于\n");
else
printf("等于\n");
return 0;
}
strcmp 函数的模拟实现
模拟思路:逐个字符比较大小
int mock_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;
}
在上面的代码中我们把返回值固定为 1 跟 -1,我们可以在这里下功夫,再简化一下代码
int mock_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
// 直接用两个字符串相减
return *str1 - *str2;
}
补充:
长度不受限制字符串函数和长度受限制字符串函数的区别
学到这里,大家可能会想:当我们在使用拷贝字符串,追加字符串时,想要拷贝或者追加固定字符数,但是上面的函数都是把一整个字符串拷贝和追加,这就是所谓的长度不受限制。下面我们介绍一下长度受限字符串函数 strncpy,strncat,strncmp,它们就能够拷贝、追加、比较固定长度的字符,其他性质跟长度不受限制函数的一样
5. strncpy 函数
char * strncpy ( char * destination, const char * source, size_t num ); //多了一个参数
功能:拷贝前num个字符串
简单使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[] = "abcd";
char ch2[20] = { 0 };
strncpy(ch2, ch1, 3);//拷贝前三个字符
printf("%s\n", ch2); // abc
return 0;
}
6. strncat 函数
char * strncat ( char * destination, const char * source, size_t num ); //多了一个参数
功能: 追加前num个字符串
简单使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[10] = "abc";
char ch2[] = "def";
strncat(ch1, ch2, 1);//追加1个字符
printf("%s\n", ch1); //abcd
return 0;
}
7. strncmp 函数
int strncmp ( const char * str1, const char * str2, size_t num ); //多了一个参数
功能:比较 str1 和 str2 前num个字符的大小
简单使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[] = "abcd";
char ch2[] = "abce";
int ret = strncmp(ch1, ch2, 3); //两字符串的前3个字符一致
if (ret > 0)
printf("大于\n");
else if (ret < 0)
printf("小于\n");
else
printf("等于\n");
return 0;
}
8. strstr 函数
函数介绍
char * strstr ( const char * str1, const char * str2 );
功能:在字符串 str1 中找字符串 str2,如果找到,函数就返回字符串 str2 在字符串 str1 中第一次出现的位置;如果没找到,函数就返回空指针 NULL
strstr 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "abcefab";
char* p;
p = strstr(str, "ce");
//返回的是第一次出现的位置
printf("%s\n", p); // cefab
return 0;
}
strstr 函数的模拟实现
模拟思路:尽量把所有情况一一列举出来,下面是我列举的三种情况
我们需要创建三个临时字符指针变量:cur 保存 str1 的起始位置,s1 保存 cur 的起始位置,s2保存 str2 的起始位置。
char* mock_strstr(const char* str1, const char* str2)
{
const char* cur = str1;
const char* s1 = NULL;
const char* s2 = NULL;
// 当str2为空指针时,直接返回str1
if (*str2 == '\0')
{
return (char*)str1;
}
// 开始逐个遍历cur
while (*cur)
{
// 用s1来保存cur的起始位置,慢慢++遍历
s1 = cur;
s2 = str2;
// 相等则继续++
while (*s1 == *s2)
{
s1++;
s2++;
}
// 直到遍历完s2确定找到完整字符串,这时返回cur的位置
if (*s2 == '\0')
{
return (char*)cur;
}
// 没找到就++继续往后寻找
cur++;
}
// 遍历完str1后都没找到,就返回空指针NULL
return NULL;
}
9. strtok 函数
函数介绍
char * strtok ( char * str, const char * delimiters );
功能:把字符串根据标记拆分开来
- delimiters 参数定义了用作分隔符的字符集合
- 字符串 str 中包含了 0 个或多个由 delimiters 字符串中一个或者多个分隔符分割的标记
- strtok 函数会在 str 中找到标记,并将其以 '\0' 结尾
- strtok 函数的第一个参数不为 NULL,函数就会在 str 中找到第一个标记,并将保存它在字符串中的位置
- strtok 函数的第一个参数为 NULL,函数就将在同一个字符串中被保存的位置开始,查找下一个标记
- 如果字符串中不存在更多的标记,就返回 NULL 指针
PS:因为 strtok 函数在分解的过程中会改变被操作的字符串,所以最好先拷贝一份
上面的解释可能有点绕,我们可以看一个例子来加深理解(实在不懂原理知道怎么用也行)
strtok 函数的使用
#include <stdio.h>
#include <string.h>
int main()
{
char ch[] = "flmz@163.com";
char str[20] = { 0 };
// 因为 strtok 函数在分解的过程中会改变被操作的字符串,所以最好拷贝一份
strcpy(str, ch);
// 标记符
const char* p = "@.";
char* s = NULL;
for (s = strtok(str, p); s != NULL; s = strtok(NULL, p))
{
printf("%s\n", s);
}
return 0;
}
结语
今天我们一起学习了字符串函数,包括函数的使用和以及简单地模拟实现;如有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!
欢迎各位在评论区友好讨论。如果觉得不错的话,麻烦您点个赞吧,十分感谢!