文章目录
前言
今天我与大家分享一下几个处理字符和字符串的库函数,我会介绍他们的使用方法和注意事项,最后会带领大家一起模拟实现一下他们的功能,话不多说让我们开始今天的学习。
strlen
使用方法与注意事项
如果大家看过我的博客,相信对这个库函数已经非常的熟悉了,但是我们还是与大家分享一下他的用法。
我们从这个库函数的介绍可以知道,他是用来求字符串长度的,参数类型是const char*
返回值类型是size_t
。什么是size_t
呢?我们可以在vs编译器里面查看
我们可以看到size_t
是无符号整形的重命名,所以strlen
的返回值是一个无符号整形。strlen
库函数在计算字符串长度时,只计算\0
之前的字符,所以被计算字符串必须有\0
。总结一下:
strlen
字符串已经\0
作为结束标志,strlen函数返回的是在字符串中\0
前面出现的字符个数(不包含\0
)
参数指向的字符串必须要以\0
结束。
注意函数的返回值size_t,是无符号的。
了解了上面这些让我们来看一道题目
#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0; }
请问上述代码输出的是什么呢?我们通过观察发现str2的长度比str1短所以strlen(str2) - strlen(str1)
应该是小于0的,所以应该输出str1 > str2
,是不是真的是这样呢?
我们发现与我们所想的结果并不相同,这是为什么呢?strlen(str2) - strlen(str1)
应该是小于0的没错,但是不要忘记了strlen
的返回值是一个无符号的整形,那么一个小于0的数他变成无符号整形后就是一个正整数,所以>0,输出str2 > str1
。我们通过这样一个例题来加深大家对strlen
返回值size_t
的理解。
模拟实现
好了我们可以模拟实现一下这个库函数,首先对函数声明进行观察,观察他的参数与返回值类型之后,我们进行模拟实现
size_t my_strlen(const char* str)
{
assert(str);
char* start = str;
char* end = str;
while (*end != '\0')
{
end++;
}
return end - start;
}
int main()
{
char* ch = "abcdefg";
int len = my_strlen(ch);
printf("%d", len);
return 0;
}
我们设置一个起点就是字符串的首元素地址,在通过遍历获得一个终点,就是字符串\0
所在的地址,我们拿终点地址减去起点地址就是他们中间字符的个数,也就是字符串的长度。当然还有其他方法,大家可以自己尝试去实现一下。
strcmp
使用方法与注意事项
通过对strcmp的描述我们了解到了,库函数strcmp
的作用是比较两个字符串的大小,他们的返回值类型是int
型,参数为两个字符指针。
标准规定
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
strcmp
库函数比较两个字符串时,是将他们的值进行比较ascii值进行比较。
模拟实现
了解了上面的内容,我们可以试着模拟实现一下库函数strcmp
。
int my_strcmp(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abad";
int ret = my_strcmp(arr1,arr2);
if (ret > 0)
{
printf(">");
}
else if (ret < 0)
{
printf("<");
}
else
{
printf("=");
}
}
strcpy
使用方法与注意事项
通过对库函数strcpy
的介绍我们知道了,strcpy
的作用是将源字符串拷贝到目标字符串,返回值类型是char*
参数是两个char*
。
关于
strcpy
我们需要注意的是
源字符串必须以\0
结束。
会将源字符串的\0
拷贝到目标空间
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
模拟实现
下面我们还是来模拟实现一下strcpy
。
char* my_strcpy(char* destination, const char* source)
{
assert(destination);
assert(source);
char* str = destination;
while (*destination++ = *source++)
{
;
}
return str;
}
int main()
{
char arr[20] = "abc";
char ch[] = "hello world";
my_strcpy(arr, ch);
printf("%s\n", arr);
return 0;
}
strcat
使用方法与注意事项
库函数strcat
的作用是将源字符串拼接在目标字符串之后,参数为两个char *
,返回值类型为`char*。
注意事项
源字符串必须以\0
结束
目标空间必须有足够大的空间,能容纳下源字符串的内容
目标空间必须可修改
字符串是不可以自己给自己追加的
模拟实现
char* my_strcat(char* destination, const char* source)
{
assert(destination);
assert(source);
char* ret = destination;
while (*destination != '\0')
{
destination++;
}
while (*destination++ = *source++)
{
;
}
return ret;
}
int main()
{
char arr[20] = "hello ";
char ch[] = "world";
my_strcat(arr, ch);
printf("%s", arr);
return 0;
}
strstr
使用方法与注意事项
strstr
库函数的作用是,判断源字符串是否是目标字符串的子串,如果是返回第一次查找到子串的地址,如果没有找到返回NULL。参数是两个字符指针,返回值类型是字符指针。
模拟实现
char* my_strstr(char* str1, const char* str2)
{
assert(str1);
assert(str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
if (*s2 == '\0')
{
return NULL;
}
while (*p)
{
s2 = str2;
s1 = p;
while ((* s1 == *s2) && s1 != '\0' && s2 != '\0')
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
}
return NULL;
}
int main()
{
char arr[20] = "abcdedefg";
char ch[] = "def";
char* ret = my_strstr(arr, ch);
if (ret == NULL)
{
printf("不存在字串");
}
else
{
printf("%s", ret);
}
return 0;
}