❤️ 作者简介 :RO-BERRY 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识,对纯音乐有独特的喜爱
日后方向 : 偏向于CPP开发以及大数据方向,如果你也感兴趣的话欢迎关注博主,期待更新
续接上篇字符函数和字符串函数上篇(详解)
我们讲解了很多字符串函数的格式、使用技巧、模拟实现以及注意事项,但是那并没有讲完,今天我们来接着讲讲剩下的字符函数和字符串函数。
我们想要查明一个字符串是不是另一个字符串的子串(子串就是一个字符串全部包含在了另一个字符串中),我们应该怎么办呢?
strstr函数就是用来验证一个字符串是否是另一个字符串的子集的函数
接下来让我们来了解一下strstr
char * strstr ( const char *str1, const char * str2);
我们知道了这个函数的格式,我们还要了解其使用方法
所谓多敲多练,我们来看看实例代码:
#include
#include
int main()
{
char str[] = "This is a simple string";
char* pch;
pch = strstr(str, "simple");
if (pch != NULL)
strncpy(pch, "sample", 6);
puts(pch);
return 0;
}
输出结果:
我们可以看到输出的是simple string,可以说明确确实实是返回了在str中simple的首字符地址,然后输出了simple string,使用的方法也是非常简单的
我们清楚了这个函数的格式以及使用,我们来模拟实现一下它
char * strstr (const char * str1, const char * str2)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1); //空指针返回str1的首元素地址
while (*cp) //循环字符串str1,循环到\0,while停止
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) ) //str1和str2都不能为\0,并且遍历的数值相等
s1++, s2++; //str1和str2都往后一格遍历
if (!*s2) //只有如果*s2为\0的时候,也就是str2遍历完的时候为成功
return(cp); //返回此时遍历的首字符地址
cp++; //循环一次str1往后遍历一格
}
return(NULL);
}
当我们有邮箱地址:[email protected]
我们想把其中的字符分割开来,也就是想取出zhangsan、yeah和yet,我们应该怎么做呢?
strtok函数就是C语言中的分片函数,我们可以通过特定的符号来将字符串分割成个个小块
char * strtok ( char * str, const char * sep );
我们采用实例来理解它的使用:
#include
#include
int main()
{
char arr[] = "[email protected]";
char sep[] = "@.";
strtok(arr, sep);
puts(arr);
}
我们会发现,只输出了第一个分割符号之前的字符串,也就是分片后的第一个字符串,射说明我们的arr的确是被修改了,那到底修改了什么呢?
我们来看看arr里存储的是什么:
我们先用strlen(arr)计算数组长度来循环输出arr
#include
#include
int main()
{
char arr[] = "[email protected]";
char sep[] = "@.";
strtok(arr, sep);
puts(arr);
for (int i = 0; i < strlen(arr)); i++)
printf("arr[%d]=%c\n",i, arr[i]);
return 0;
}
我们上次讲过,strlen函数是以\0为结束判断条件,那就证明要么是arr后面的元素都被删除了,要么是后面一个元素变成了\0;
接下来我们在使用sizeof来遍历,它不会以\0为终止
可以看到,我们的arr后面的内容并没有删除,而是将第一个遇到的分隔符转换成了\0,这样的话我们可以输出分割出来的第一个字符串。
上例,我们可以看到,strtok是可以改变源字符串的内容的,会将遇到的第一个分割符号改写为\0,所以我们如果不希望修改源字符串,我们需要去拷贝一个新的字符数组。
那么我们知道了其使用原理,那么我们如何将所有的想要的字符串打印出来呢?
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 如果字符串中不存在更多的标记,则返回 NULL 指针。
我们再来通过代码进行验证;
#include
#include
int main()
{
char arr[] = "[email protected]";
char sep[] = "@.";
char copy[20];
strcpy(copy, arr);
char* ret = NULL;
for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
printf("%s\n", ret);
return 0;
}
通过利用其性质,我们就可以完成我们想要的操作
这个函数使用的比较少我们可以稍作了解,知道这个函数的使用就可以了
【扩展】库函数在执行的时候,发生了错位,会将一个错误码存放在errno这个变量中,errno是C语言提供的一个全局的变量
错误信息会转换为错误码,错误码在计算机中用0、1、2、3等编号代替
strerror函数是帮我们实现错误报告的函数,它可以将错误码转换成错误信息,我们就可以知道错误是什么
char * strerror ( int errnum );
我们先来看看计算机中错误有哪些:
int main()
{
for (int i = 0; i < 10; i++)
printf("错误码i:%s\n", i, strerror(i));
return 0;
}
通过这个函数我们可以清晰的看到错误码对应的错误信息是啥
接下来我们来测试一下:
文件操作后面会涉及到,这里我们简略讲解一下:
由于我们没有创建data.txt,我们这里故意创造了一个错误,但不是编译错误,再输出错误码对应的错误信息。
它说没有对应的文件,正好是我们想要的错误
我们这里扩展一个函数:perror
⚡perror函数可以省略printf函数,很简便,同时能转换错误码的信息,前面输出我们出现错误的操作,但是这个函数需要我们对应需要检测的操作,而strerror函数只需要给它错误码即可
我们的字符有很多种形式,有数字,小写字母,大写字母,空格等等;
计算机可以帮我们识别出他们吗?
接下来让我们看看字符分类函数:
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母az或AZ |
isalnum | 字母或者数字,az,AZ,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
这就是我们相关的字符分类函数,我们只需要稍做了解,重点还是前面的字符串函数。
我们的字符函数以及字符串函数讲解就到此为止了,其他内容敬请关注。希望我所写的博客能对你有所帮助,编程学习之路还很漫长,需要我们一点一滴去积累
低头赶路,敬事如仪
自知自心,其路则明