字符函数和字符串函数

前言 

字符分类函数 

这些字符分类函数都是类似的,返回值都是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作用

总结 

这就是字符函数和字符串函数。接下来下一篇将会讲内存函数 ,敬请期待,谢谢各位的支持!

  • 30
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值