❤️ 作者简介 :RO-BERRY 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识,对纯音乐有独特的喜爱
📗 日后方向 : 偏向于CPP开发以及大数据方向,如果你也感兴趣的话欢迎关注博主,期待更新
字符函数和字符串函数2
- 1.strstr
- 1.1 strstr格式
- 1.2 strstr函数的使用
- 1.3 strstr的模拟实现
- 2.strtok
- 2.1 strtok格式
- 2.2 strtok函数的使用
- 2.2.1
- 3.strerror
- 3.1strerror格式
- 3.2 strerror函数的使用
- 3.字符分类函数
- 后记
🍟续接上篇字符函数和字符串函数上篇(详解)
我们讲解了很多字符串函数的格式、使用技巧、模拟实现以及注意事项,但是那并没有讲完,今天我们来接着讲讲剩下的字符函数和字符串函数。
1.strstr
我们想要查明一个字符串是不是另一个字符串的子串(子串就是一个字符串全部包含在了另一个字符串中),我们应该怎么办呢?😮
🐥strstr函数就是用来验证一个字符串是否是另一个字符串的子集的函数
接下来让我们来了解一下strstr
1.1 strstr格式
char * strstr ( const char *str1, const char * str2);
- 1.返回值为char*类型
在www.cplusplus.com中有对其的解释也就是说,如果第二个字符串是第一个字符串的子集,那么将会返回第二个字符串在第一个字符串的位置的首元素地址;如果不是,则会返回null,也就是空指针 - 2.函数参数为 const char *str1, const char * str2
str2为验证的子串,str1为源字符串
1.2 strstr函数的使用
🍖我们知道了这个函数的格式,我们还要了解其使用方法
所谓多敲多练,我们来看看实例代码:
#include <stdio.h>
#include <string.h>
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,使用的方法也是非常简单的
1.3 strstr的模拟实现
我们清楚了这个函数的格式以及使用,我们来模拟实现一下它
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);
}
2.strtok
当我们有邮箱地址:zhangsan@yeah.net
我们想把其中的字符分割开来,也就是想取出zhangsan、yeah和yet,我们应该怎么做呢?
🐥strtok函数就是C语言中的分片函数,我们可以通过特定的符号来将字符串分割成个个小块
2.1 strtok格式
char * strtok ( char * str, const char * sep );
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记。 - strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
- strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。) - strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
2.2 strtok函数的使用
2.2.1
我们采用实例来理解它的使用:
#include<stdio.h>
#include<string>
int main()
{
char arr[] = "zhangsan@yeah.net";
char sep[] = "@.";
strtok(arr, sep);
puts(arr);
}
输出结果:
我们会发现,只输出了第一个分割符号之前的字符串,也就是分片后的第一个字符串,射说明我们的arr的确是被修改了,那到底修改了什么呢?🤨
我们来看看arr里存储的是什么:
我们先用strlen(arr)计算数组长度来循环输出arr
#include<stdio.h>
#include<string>
int main()
{
char arr[] = "zhangsan@yeah.net";
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<stdio.h>
#include<string>
int main()
{
char arr[] = "zhangsan@yeah.net";
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;
}
输出结果为:
通过利用其性质,我们就可以完成我们想要的操作
🍟这个函数使用的比较少我们可以稍作了解,知道这个函数的使用就可以了
3.strerror
🧈【扩展】库函数在执行的时候,发生了错位,会将一个错误码存放在errno这个变量中,errno是C语言提供的一个全局的变量
错误信息会转换为错误码,错误码在计算机中用0、1、2、3等编号代替
🐥strerror函数是帮我们实现错误报告的函数,它可以将错误码转换成错误信息,我们就可以知道错误是什么
3.1strerror格式
char * strerror ( int errnum );
- 1.char*返回的是错误码对应的错误信息首字符地址
- 2.参数是错误码
3.2 strerror函数的使用
我们先来看看计算机中错误有哪些:
int main()
{
for (int i = 0; i < 10; i++)
printf("错误码i:%s\n", i, strerror(i));
return 0;
}
输出结果为:
通过这个函数我们可以清晰的看到错误码对应的错误信息是啥
接下来我们来测试一下:
🎄文件操作后面会涉及到,这里我们简略讲解一下:
- 文件的操作需要打开,读写,关闭,我们在打开也就是fopen的时候,需要传入文件名以及读还是写的操作,“r”就是读(read),“w”就是写(write)
由于我们没有创建data.txt,我们这里故意创造了一个错误,但不是编译错误,再输出错误码对应的错误信息。
它说没有对应的文件,正好是我们想要的错误
我们这里扩展一个函数:perror
⚡perror函数可以省略printf函数,很简便,同时能转换错误码的信息,前面输出我们出现错误的操作,但是这个函数需要我们对应需要检测的操作,而strerror函数只需要给它错误码即可
3.字符分类函数
我们的字符有很多种形式,有数字,小写字母,大写字母,空格等等;
计算机可以帮我们识别出他们吗?
接下来让我们看看字符分类函数:
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
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 | 任何可打印字符,包括图形字符和空白字符 |
这就是我们相关的字符分类函数,我们只需要稍做了解,重点还是前面的字符串函数。
后记
我们的字符函数以及字符串函数讲解就到此为止了,其他内容敬请关注。希望我所写的博客能对你有所帮助,编程学习之路还很漫长,需要我们一点一滴去积累
低头赶路,敬事如仪
自知自心,其路则明