hello,大家好!今天给大家分享一些常用的库函数,掉发制作,求赞支持一下啦!☺☺
一、strlen函数
①全称string length,是计算字符串长度的相关函数,以 ‘\0’ 作为结束标志,strlen函数返回的是 “\0”之前出现的字符串个数(不包括\0);
②参数指向的字符串必须以“\0”结束;
③注意函数的返回值为size_t , 是无符号的整型(重点记)
上代码:
int main()
{
if(strlen("abc")-strlen("abcdef")>0) //3-6
{
printf("大于\n");
}
else
{
printf("小于等于\n");
}
return 0;
}
像上述这种情况,你们觉得应该输出什么?大多数人都会认为是“小于等于” ,但其实不然,这就牵扯到了strlen函数的返回值size_t,无符号整型,所以即使是3-6=-3<0,他也不会是-3,而是3>0,输出的是“大于”,那怎么改才能是预想的输出结果呢?上图:
这样强制类型转换,就得到了想要的输出结果。
④strlen的使用需要包含头文件(#include<string.h>)
下边来看 一段模拟实现的代码:
#include<stdio.h>
#include<string.h>
size_t my_strlen(const char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
size_t len = my_strlen(arr);
printf("%zd\n", len);
return 0;
}
我们自己写一个函数来实现strlen库函数的功能,必须是遇到 ‘\0’ 才会停止。
二、strcpy函数
其中还包含两个参数,destination(目的地)和source(源头数据)
①字符串拷贝,并包含终止符,源字符串必须以‘\0’结束;
②将源字符串中的‘\0’拷贝到目标空间;
③目标空间必须足够大,以确保能存放源字符串;
④目标空间必须可修改。
图中库函数strcpy的使用,但是我们这样无法直观的看出‘\0’是否被拷贝,接下来我们来调试一下:
这么一看就直观很多了,图中红色部分显然包含‘\0’,
我们来模拟实现一下:
void my_strcpy(char* dest, char* sour)
{
assert(dest != NULL);
assert(sour != NULL);
while (*sour != '\0')
{
*dest++ = *sour++;
}
*dest = *sour;
}
int main()
{
char arr1[20] = "xxxxxxxx";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
其实这个代码还可以简化,
这个简单了解一下就可以了。
三、strcat函数
如图,同样也有两个参数destination和source,destination字符必须可以修改(不能加const),两个字符串必须带有终止字符。
①源字符串必须以“\0”,结束;
②目标字符串也得有“\0”,否则没办法知道追加从哪里开始;
③目标空间必须足够大,能容下源字符串内容;
④目标空间必须可修改。
我们自己试着以同样的原理来模拟实现一下:
【 注意 】:有一些小伙伴有疑问,那这个模拟实现的程序可不可以自己追加自己?答案当然是不可以!如果在当dest找到“\0”时,sour开始行动,dest=sour,第一个就会将‘h’覆盖掉‘\0’,从此以后sour再也找不到‘\0’,这就很有可能陷入死循环,然后越界访问,最后导致程序崩溃,尽量不要出现这样的情况。
四、strcmp函数
字符串的比较,怎么比较呢,就是比较两个字符串对应位置字符的大小(根据ASCLL码表), 而①不是比较字符串的长度,②返回值是一个int整型 。
接下来,我们还是来模拟实现一下strcmp函数的原理:
五、strncpy、strncat、strncmp函数
这三个函数与上述的strcpy,strcat,strcmp函数都有什么不同点,或者说他们之间有什么联系。上边我们提到的的这三个函数是长度不受限的字符串函数,在VS看来它们是不安全的;而strncpy、strncat、strncmp这三个函数是长度不受限的字符串函数,相对来说是安全的;
①strncpy函数,当你规定了复制长度之后,你说复制几个,它就复制几个,看下图调制结果,细心的小伙伴就发现了为什么没有‘\0’,在这个地方当你规定了长度之后就没有‘\0’的事了,
那如果说我输入的长度大于字符串的原有长度又会出现怎样的情况呢?
你让我cpy几个我就来几个,那不够的话我就给你打印‘\0’。
②strncat函数
在‘hello’后追加4个字符串后我在加个‘\0’,我得保证追加完了之后还是一个字符串 。
同样的,如果超出了追加的字符串长度,会出现什么情况?
即使你让我复制7个字符,但是我只有5 个再外加一个‘\0’,到第七个的时候没有了,那我就不会再追加了。
③strncmp函数
返回值仍然是int ,你让我比较几个我就比较几个,注意不要超过原有长度,不要给自己创造bug。
六、strstr函数
这个函数的作用是在一个字符串str1中找是否存在一个子串str2,如果有就返回str2在str1中第一次出现的位置,即使你出现好几次,但是我只返回第一次出现的位置,返回类型是char*。
我们来程序运行一下:
找到‘def’第一次出现的位置之后,打印之后的所有字符串。
我们自己先一个代码来模拟实现一下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(const char *str1,const char *str2)
{
const char* cur = str1;
const char* s1 = NULL;
const char* s2 = NULL;
assert(str1 && str2);
if (*s2 == '\0')
{
return (char*)str1;
}
while (*cur)
{
s1=cur;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++
}
if (*s2=='\0')
{
return (char*)cur;
}
cur++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefabcdef";
char arr2[] = "def";
char* ret = my_strstr(arr1, arr2);
if (ret != NULL)
printf("%s", ret);
else
printf("找不到\n");
return 0;
}
七、strtok函数
char * strtok ( char * str , const char * sep ) ;
①sep参数指向一个字符串,定义了用作分隔符的字符串集合;
② 第一个参数指定一个字符串,它包含了0个或多个有sep字符串中一个或多个分隔符分割的标记
③strtok函数找到str中下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针;
【注】:strtok函数会修改被操作的字符串,所以一般都是用临时拷贝的、可修改的内容进行操作
④strtok函数:
a.第一个参数不为NULL,函数将找到str中第一个标记并保存它在字符串中的位置,
b.第一个参数为NULL,函数将从同一个字符串中被保存的位置开始,查找下一个标记;
⑤如果字符串中不存在更多的标记,则返回NULL指针。
我们自己可以试着写一串代码来实现一下:
int main()
{
char arr[] = "zhangsan@qq.com";
char arr1[30] = { 0 }; //zhangsan\0qq\0com
strcpy(arr1, arr);
const char* p = "@.";
char* s = NULL;
for (s = strtok(arr1, p); s != NULL; s = strtok(NULL, p))
{
printf("%s\n", s);
}
return 0;
}
我们来看运行结果:
八、strerror函数
char * strerror ( int errnum );
【注意】头文件!!!
那这个函数具体在程序中有什么用呢?
①strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来;
②在不同的系统和C语言标准库的实现中都规定了一些错误码,一般是放在头文件中,这个头文件说明C语言程序启动的时候就会使用一个全局变量errno来记录程序的当前错误码,只不过程序启动的时候errno为0;
③我们在使用标准库中的函数的时候如果发生了某种错误,就会将对应的错误码放在errno中,因为一个错误码是数字很难理解,所以每个错误码都有对应的错误信息,strerror函数就会将错误所对应的信息字符串地址返回。
最后结果按预期输出,自己也可以临时创建一个新文件验证一下(注意文件扩展名!!!)
如果上一个库函数出错之后,下一个又出错了,那么它返回的就是下一个库函数的错误,全局变量errno在每一次发生错误之后都会更新。
与此同时,我们还可以了解一下perror函数,它就更直接了,他可以直接将错误信息打印出来
它可以打印完参数部分的信息之后,再打印一个冒号和一个空格,最后再打印错误信息。
根据自己的需求,正确的使用这些函数。
好了,这期的分享就到这里,我们下次再见,拜拜~~~