前言:
当我们在写代码的时候,合理的使用库函数可以大大提高写代码的速度,也可以提高代码的可读性,接下来就让我们了解一些字符串的库函数是如何使用的
常用字符串库函数的分类
1.strlen—求字符串长度
1.1 strlen的使用
strlen函数是求字符串长度的函数,统计的是字符串中'\0'前的字符个数。(不包含'\0')
注:字符串中必须要有'\0'
字符串的返回值是size_t(无符号),并且要包含头文件<string.h>,在cplusplus中明确指出:
strlen函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = { "abcd" };
int sum = strlen(arr);
printf("%d\n", sum);
return 0;
}
在字符串中存放着abcd\0,strlen函数计算\0的元素,所以输出的数字是4
1.2strlen的模拟实现
1.2.1使用计数器实现strlen模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
int count = 0;
assert(str);
while (*str)
{
str++;
count++;
}
return count;
}
int main()
{
char arr[] = "abcd";
int sum=my_strlen(arr);
printf("%d", sum);
return 0;
}
1.2.2使用指针减去指针实现strlen函数
#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);
char* p = (char*)str;
while (*p != '\0')
{
p++;
}
return p - str;
}
int main()
{
char arr[] = { "abcde" };
int sum = my_strlen(arr);
printf("%d", sum);
return 0;
}
1.2.3使用递归实现strlen函数
#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);
if (*str == '\0')
{
return 0;
}
else
return 1 + my_strlen(str + 1);
}
int main()
{
char arr[] = { "abcde" };
int sum = my_strlen(arr);
printf("%d", sum);
return 0;
}
2.strcpy—拷贝字符串
2.1strcpy的注意及使用
这里的destination是目标空间,source是源
注意:
1.源字符串中必须要有'\0'(如果没有\0就找不到什么时候停下来)
2.拷贝时\0也会拷贝到目标空间中
3.目标空间的内存要充裕,确保可以存放源字符串
4.目标空间必须可以修改
strcpy的使用:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "hello world";
char arr2[20] = { 0 };
strcpy(arr2, arr1);
printf("%s", arr2);
return 0;
}
运行结果:
2.2strcpy的模拟实现
#include<stdio.h>
#include<string.h>
void my_strcpy(char* dest, const char* src)
{
while (*src != '\0')
{
*dest = *src;
src++;
dest++;
}
*dest = *src;
}
int main()
{
char arr1[] = { "hello word" };
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s", arr2);
return 0;
}
相信大家都可以看懂这段代码,但这段代码并不是很好,有些冗余,我们可以对其进行优化补充
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[] = { "hello word" };
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s", arr2);
return 0;
}
1.首先进行了assert断言来判断两个地址的有效性
2.接下来优化while循环里的内容,将*dest++ = *src++放入到while的判断条件中,当*src是\0时,就会跳出循环,\0的ASCII码值是0,所以会跳出循环
3.在cplusplus中指出返回destination,所以我们需要建立一个临时变量来存放dest的初始值
4.这样优化可以提高代码的可读性
3.strncpy
3.1strncpy的使用
strncpy的使用和strcpy的使用非常相似,strncpy是拷贝几个字符到目标字符串
在使用strncpy的时候在后面加上想要拷贝几个字符即可
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = { "abcd" };
char arr2[] = { "erd" };
strncpy(arr2, arr1, 2);
printf("%s", arr2);
return 0;
}
运行结果
3.2strncpy的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncpy(char* dest, const char* src,size_t sz)
{
assert(dest && src);
char* ret = dest;
while (sz--)
{
*dest++ = *src++;
}
return ret;
}
int main()
{
char arr1[] = { "hello world" };
char arr2[20] = { 0 };
my_strncpy(arr2, arr1,5);
printf("%s", arr2);
return 0;
}
4.strcat—连接字符串
4.1strcat的注意及使用
strcat函数就是追加一个sourse的字符串到destination字符串中
注意:
1.源字符串和目标字符串必须包含\0,否则不知道从哪里开始也不知道在哪里结束。
2.目标空间必须要足够大,足够存放追加的字符串。
3.目标空间必须可以修改。(不要存放常量字符串)
strcat的使用:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = { "hello " };
char arr2[] = { "world" };
strcat(arr1, arr2);
printf("%s", arr1);
return 0;
}
运行结果:
4.2strcat的模拟实现
首先我们要找到destination中的\0,然后再将sourse的字符串拷贝到destination中
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
//1.寻找目标字符串的\0
while (*dest != '\0')
{
dest++;
}
//2.拷贝字符串到目标空间
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = { "hello " };
char arr2[] = { "world" };
my_strcat(arr1, arr2);
printf("%s", arr1);
return 0;
}
5.strncat
5.1strncat的使用
strncat和strcat的使用也非常相似,在函数中加入想要追加的字符即可
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = { "hello " };
char arr2[] = { "worldxx" };
strncat(arr1, arr2, 5);
printf("%s", arr1);
return 0;
}
运行结果:
5.2strncat的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncat(char* dest, const char* src,size_t sz)
{
assert(dest && src);
char* ret = dest;
//1.寻找目标字符串的\0
while (*dest != '\0')
{
dest++;
}
//2.拷贝字符串到目标空间
while (sz--)
{
*dest++ = *src++;
}
*dest='\0';
return ret;
}
int main()
{
char arr1[20] = { "hello " };
char arr2[] = { "world" };
my_strncat(arr1, arr2,2);
printf("%s", arr1);
return 0;
}
6.strcmp—字符串的比较
6.1strcmp的注意及使用
注意:
1.strcmp要包含头文件<string.h>
2.strcmp函数比较的是两个字符串相对应的ASCII码值
3.第一个字符串大于第二个字符串返回一个大于0的数字
4.第一个字符串和第二个字符串相等返回0
5.第一个字符串小于第二个字符串返回一个小于0的数字
strcmp的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1 []= { "abcd" };
char arr2 []= { "abbd" };
int ret = strcmp(arr1, arr2);
printf("%d", ret);
return 0;
}
运行结果,因为c的ASCII码值大于b的ASCII码值,所以应该返回一个大于0的数字
6.2strcmp的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str2 == '\0')
{
return 0;
}
str2++;
str1++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = { "abcd" };
char arr2[] = { "abd" };
int ret = my_strcmp(arr1, arr2);
printf("%d", ret);
return 0;
}
7.strncmp
7.1strncmp的使用
strncmp函数就是你想要我比较几个字符我就比较几个字符
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = { "abdc" };
char arr2[] = { "bcdc" };
int ret=strncmp(arr1, arr2, 2);
printf("%d", ret);
return 0;
}
运行结果,因为这里只需要比较前两个字符的ASCII码值,所以就是arr1中的ab和arr2中的bc相比,b的ASCII码值大于a的ASCII码值,所以返回一个小于0的数字
7.2strncmp的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strncmp(const char* str1, const char* str2,size_t sz)
{
assert(str1 && str2);
while (*str1 == *str2 && sz!=1)
//如果输入1的话就是字符了,而不是字符串
{
if (*str2 == '\0')
{
return 0;
}
sz--;
str2++;
str1++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = { "abcd" };
char arr2[] = { "abd" };
int ret = my_strncmp(arr1, arr2,2);
printf("%d", ret);
return 0;
}
8.strstr—在一个字符串中查找另一个字符串
8.1strstr的注意及使用
注意:
1.strstr函数其实就是在str1中找str2第一次出现的位置(如果有多次出现也是返回第一次出现的位置)
2.如果str1中找不到str2的字符串,那就打印null
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = { "this is a flower" };
char arr2[] = { "is" };
char* ret=strstr(arr1, arr2);
printf("%s", ret);
return 0;
}
运行结果:这里arr1中找arr2的is,在this中找到了第一个is,所以就返回第一个is的地址,打印is后面的内容
8.2strstr的模拟实现
strstr模拟实现当中会出现多种状况,让我们来分析一下
特殊场景:当str2是空字符串时,我们直接返回str1
代码实现:
#include<stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
const char* s1 = NULL;
const char* s2 = NULL;
const char* cur = str1;
if (*str2 == '\0')
{
return (char*)str1;
}
while (*cur)
{
s1 = cur;
s2 = str2;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;
}
cur++;
}
return NULL;
}
int main()
{
char arr1[] = { "this is a flower" };
char arr2[] = { "is" };
char* ret = my_strstr(arr1, arr2);
if (ret != NULL)
{
printf("%s\n", ret);
}
else
printf("找不到\n");
return 0;
}
运行结果:
这些就是比较常用的字符串函数了,有兴趣的友友可以看一下,欢迎指导