前言
字符分类函数
这些字符分类函数都是类似的,返回值都是int,假如我们用islower,如果参数是小写字母,则返回非0的随机数,如果不是则返回0.
参数类型也要是int,但我们输入的不仅可以为整数(字符的ascall码值),也可以是单个字符(因为其类型差距过小,所以系统直接帮其隐式转换)。
这些字符分类函数如下
不要求强记, 知道几个很简单的就行,islower,isupper。其他的到时候要用到的话再回来看下就行。
其头文件都为#include<ctype.h>,这个为新学的头文件 。
字符转换函数
大写字母的ascall码值比小写字母小32,所以小写字母转换为大写只需要减32就行。(存在隐式转换)
而我们也可以直接用函数去直接转换
头文件都为#include<ctype.h>,返回值为ascall码,参数也为ascall码,不过不重要,依然可以参数为字符(有隐式转换)。
getchar和putchar
getchar
int getchar(void) 所以是getchar(),其作用原理是接收缓冲区的单个字符,并返回字符的ascall码值。
如果缓冲区没有字符,则我们要自己输入数字。
如果缓冲区有剩余的字符,则直接用它,不用自己输入。
我们还要知道在我们输入值时,我们键盘中的enter键在输入后会使我们的缓冲区多个\n。而空格键在输入后同样代表着使缓冲区多个空格字符。至于缓冲区\n和空格字符,并不是所有函数全都不能识别。有些函数能识别,有些函数不能识别,遇到它就会终止。依据函数而定。这方面的知识说实话有点抽象。所以依据这上述知识在面对一些问题时就会出现bug。
就是因为在输入完abcdef之后来了个enter键,这下缓冲区又多了个\n,而scanf不能识别\n,所以
会多个 \n,而getchar由于多出来个\n,就直接接收\n,不用自己输入,从而ch是\n,导致还没输入就出结果,所以需要两个getchar,且在enter完之后就输入字符,(不能再输入空格,其也会被识别,会导致结果错误)
putchar
putchar的使用是直接putchar(),括号中为字符的ascall码形式或者字符形式(因为会隐式转换,所以哪种都行,不要纠结其putchar参数为哪种类型它接收就必须该种类型,因为隐式转换导致不只是必须为该类型)
作用就是直接以字符形式打印出来,打印出字符形式。返回值为其字符的ascall码值(int)。
这个相比于getchar简单了些,因为getchar涉及了缓冲区,其更为复杂。
对于getchar和putcha这篇文章有更详细的解释
https://blog.csdn.net/2201_75743654/article/details/131829012
两者头文件
都为#include<stdio.h>
strlen函数
strlen我们之前就学过,这里就不详细讲,对于其模拟有三个方式,第三个方式是不创建临时变量的方式,用了函数递归去实现。
头文件为#include <string.h>
从接收的地址里的内容如果等于\0,则结束,如果不是,则将指针+1,直到等于\0,返回值为测出\0前面的个数(不算上\0自己)。
其中这里值得讲的一个是其返回值为size_t,其为无符号整数,有个易错的地方,如下
因为3,6为无符号整数,从而相减得出-3其也为无符号整数,-3转化为无符号整数就为 2的32次方加3,从而为正,输出大于。
不是我们想当然的输出小于。
strcpy函数
strcpy是将source的那部分直接拷贝到destination那,其中参数类型如上。
其中需要注意的一点是source中拷贝是指向的内容遇到\0再终止,包括\0一起移动到目标地。
还需注意左边的目标参数类型为char*,右边源头参数类型为const char* 。
其返回值为destination的原本的首位地址。
模拟strcpy函数没什么好讲的
只需要注意其两个为后置++,在赋值完后才执行。所以才能这么写。
头文件为 #include<string.h>
0的一些区别认知
第四个nul,NUL代表着\0.
其他没什么好说的。
strcat函数
没什么必须要讲的,其函数格式跟strcpy格式一摸一样
strcat跟strcpy有点类似,只不过该函数是从目标函数的第一个\0时开始作用链接。而strcpy是最开始就作用。就多了一个这个。
而还要额外说一个点,能否自己链接自己。如果按照我们模拟的代码来说,其会造成死循环而后越界访问。
但是strcat库函数代码实现方式肯定跟我们不一样,更高级,其可以实现自己连接自己 。但我们还是建议即使它能实现,还是不要用strcat库函数去实现自己连接自己,风险还是有点高。
返回值为目标首个元素地址,跟strcpy一样
头文件#include<string.h>
strcmp函数
在之前就有讲到strcmp函数 ,在这篇文章中
https://blog.csdn.net/Easonmax/article/details/134718250?spm=1001.2014.3001.5501
这里就不讲了
上面是该函数的模拟实现。
长度限制函数
前文
由于前面三个函数 strcat strcpy strcmp 没有长度限制而直接运行,vs编译器认为不安全,在没有
的情况下会直接报错,不让运行。
例子如下
所以我们就多了这三个函数,有长度限制的函数,vs认为其很安全。
strncpy
strncpy 如果num小于字符串长度,则直接取出其对应的字符 (后面不带\0),对应什么就拿什么。 如果超过其字符串长度,超过的部分都为\0。
这是其细节部分。
这里还要说一点,一个程序员非要找bug的话你是拦不住他的,不要故意制造一些bug。比如将9个的字符串复制到5个空间大的目标处。这是故意找bug
strncat
strncat当num小于字符串长度时,其会将本来的字符部分外加\0追加到末尾。而strncpy当小于字符串长度时,不会主动添加\0。
当num大于字符串长度时,其只会将整个字符串追加到目标处(包括\0,只有一个) 。而strmcpy当大于时会将超过的部分都变为\0(会有多个\0)。
这就是其strncat更多细节
对于自己给自己追加,我们就可以用strncat实现,长度为字符串长度。不要用strcat实现自己给自己追加。(有长度限制,相比另一个更安全)
一个程序员想制造bug是拦不住的 ,不要故意制造一些bug。
strncmp
这个没什么较多细节,就是对比较的长度进行限制。
当然不要故意制造bug,使比较长度大于本身字符串长度 。
头文件
头文件都为 #include<string.h>
其三个函数模拟实现就不说了。
strstr
strstr会返回 str2在str1的第一次地址 ,前提要str1中有str2(不包含\0)。如果没有,则返回NULL.
str2如果为空字符串(空字符串为“”,里面只有一个\0),则strstr返回str1字符串的首位元素地址。c语言规定的。
所以模拟实现为上述代码。
strtok
这个strtok函数本质太过复杂,这里就不模拟其函数和讲它的本质。就讲下他该如何用。
当我们要分割一个字符串时,就用strtok 。其格式为
举个例子,如
#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
int main()
{
char arr[] = "dsah..dh45.dads45";
printf("%s\n",strtok(arr, "."));
printf("%s\n", strtok(NULL, "."));
printf("%s\n", strtok(NULL, "."));
printf("%s\n", strtok(NULL, "."));
}
第一次我们要输入arr,从而第一个间隔符变为\0,且返回最开始的d位置的地址。保存的地址变为间隔符后面的符号的。
当有几个间隔符连续在一块时,只需要一个strtok就能处理,不用多个。(但是其只会第一个间隔符变为\0,保存的地址变为d的地址(..d处的),经调试知道)
当我们之后再用strtok作用该函数时,只需第一个参数输入NULL,其地址从第一次用过后保存的地址开始。然后将后面的第一个间隔符变为\0,在我们这就是5后面的.变为\0,返回d位置的(..d处的)地址。地址变为d的地址(45.d处的)
当我们第三次用时,由于后面无标记符,不会再有变为\0的操作,但最后有个\0,所以还是会返回d位置的(45.d处的)地址。
但我们第四次用时就什么都没有了,返回NULL.
strtok会改变字符串arr的值。 会使字符串arr改变(间隔符变为\0)(经调试得出)
用这段代码能高效率实现对该字符串的分割。
头文件依然为#include<string.h>
strerror
strerror
系统规定了一些错误码,这些错误码为整数,很难理解什么意思,所以这些错误码都是有对应的错误信息的,这些错误信息我们就能看懂。
所以我们就能用strerror去得到错误码对应的错误信息的地址,其格式如上。
这里我们利用上述知识打印下0到九错误码对应的错误信息
int main() {
for(int i=0;i<10;i++)
{
printf("%s\n", strerror(i));
}
}//打印0到9错误码对应的错误信息
当我们系统发生错误时,会将其对应的错误码放入errno全局变量中。
在开始时没错误发生,error是0,对应着没错误,后面有错误时,其值会发生变化。
如果有多个错误,则其值会不断更新,最终结果为为最终错误的错误码
要用errno这个全局变量必须得用头文件#include<errno.h> 才能使用
举个例子
fopen函数如果执行成功,能打开这个文件“unexist.ent”则会返回一个指针。如果执行失败则会返回NULL,因为不存在该文件,所以执行失败,errno就会得到一个错误码 ,从而通过该代码打印出 错误信息
strerror函数头文件依然为#include<string.h>
perror
perror头文件为#include<stdio.h>
作用是先输出里面的str字符串,再输出个冒号和空格,而后直接输出目前的errno对应的错误信息(errno一直存在,里面存放着错误码,如果要用就必须使用对应头文件)。
所以我们也可以通过perror去实现跟strerror一样的效果
该代码证明了perror的作用 。 此时errno由于无错误,所以错误码为0,错误信息就为 No error ,所以打印出以上信息。
上面的图也是一个例子去证明其perror作用
总结
这就是字符函数和字符串函数。接下来下一篇将会讲内存函数 ,敬请期待,谢谢各位的支持!