当前位置: 首页 > news >正文

C语言零基础第15讲:字符函数和字符串函数

目录

1.字符分类函数

2.字符转换函数

3.strlen的使用和模拟实现

4.strcpy的使用和模拟实现

5.strcat的使用和模拟实现

6.strcmp的使用和模拟实现

7.strncpy的使用

8.strncat的使用

9.strncmp的使用

10.strstr的使用和模拟实现

11.strtok函数的使用

12.strerror函数的使用


正文开始

        在写代码的过程中,我们可能经常要处理字符和字符串,为了方便操作字符和字符串,C语言标准库提供了一系列库函数。我们可以一起来看看:

1.字符分类函数

        C语言中有一批函数,是专门对字符进行分类的,这些函数对应的头文件是:ctype.h

        我们来看个例子:

        我们来做一个练习:找出数组中的十进制数字,并打印出来。如下:

        我们再来看一个练习:写一个代码,将字符串中的小写字母转为大写字母,其他字符不变。如下:

2.字符转换函数

        C语言中提供了2个字符转换函数:

  1. int tolower( int c ); :将参数所传进去的大写字母转为小写字母。
  2. int toupper ( int c ); :将参数所转进去的小写字母转为大写字母。

        将小写转大写,可以用-32来完成。将大写转小写,可以用+32来完成。不过,有了字符转换函数,我们可以直接转换。

        我们可以来看看例子:

3.strlen的使用和模拟实现

        strlen函数的原型如下:

size_t strlen( const char* str);
  1. 参数指向的字符串,必须要以'\0'结束。
  2. strlen函数返回的是,字符串中在'\0'前面出现的字符个数(不包含'\0')。
  3. 对应的头文件是:string.h。
  4. 返回值类型为size_t,是无符号的。

        对于返回值类型为size_t这一点,是一个易错点。请看下面的例子:

        对于上面的代码,我们可能会觉得,arr2的长度比arr1短,那么应该会打印arr2 <= arr1。然而结果是arr2 > arr1。这是因为,strlen函数的返回值是无符号整数,两个无符号数相减,得到的还是无符号数。我们知道,两个长度相减,得到的是-3,存储的也是-3的补码,但由于是无符号整型,这个补码会被当做原码,会变成一个很大的无符号数。

        如果想要实现原意,可以这样进行强制类型转换:(int)strlen(arr2) - (int)strlen(arr1)。或者这样写:if(strlen(arr2) > strlen(arr1))。

        我们来看看strlen的模拟实现:

4.strcpy的使用和模拟实现

        strcpy函数的原型如下:

char* strcpy(char* destination, const char* source);

    

  1. 前一个参数是目标字符串的指针,要将被复制的内容赋给目标字符串,所以不加const修饰。
  2. 后一个参数是源字符串的指针,仅仅是复制源字符串的内容,不做任何修改,所以使用const修饰。
  3. 源字符串必须以'\0'结束,这个'\0'也会被拷贝到目标空间。
  4. 目标空间必须足够大,以确保能够存放得下源字符串。
  5. 目标空间必须是可修改的。
  6. 对应的头文件:string.h。

        我们来看一个示例:

        我们来看看strcpy的模拟实现:

5.strcat的使用和模拟实现

        strcat函数的原型如下:

char* strcat (char* destination, const char* source);
  1. 把源字符串的内容追加到目标字符串的后面。
  2. 源字符串必须以'\0'结束。
  3. 目标字符串也得有'\0',否则不知道从哪里开始追加。
  4. 目标空间必须足够大。
  5. 目标空间必须可修改。
  6. 对应的头文件:string.h。

        我们来看一个示例:

        我们再来看看strcat的模拟实现:

6.strcmp的使用和模拟实现

        strcmp函数的原型如下:

int strcmp (const char* str1, const char* str2);
  1. 意为string compare,即字符串比较。
  2. 比较的是2个字符串的大小,第一个字符串大于第二个字符串,则返回一个大于0的数字,等于则返回0,小于则返回一个小于0的数字。
  3. 按字符的ASCII码值从左向右逐个比较, 直到遇到不同的字符,或者'\0'。
  4. 比如:"abchigk"和"abcpqrs",前面的字符都是abc,直到遇到了h和p作比较,显然p的ASCII码值要更大,所以结果为前一个字符串<后一个字符串,返回一个小于0的数字。
  5. 对应的头文件是:string.h。

        我们来看一个示例:

        我们来看一下strcmp函数的模拟实现:

7.strncpy的使用

        strncpy函数的原型如下:

char* strncpy (char* destination, const char* source, size_t num);
  1. 从源字符串拷贝num个字符到目标空间。
  2. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
  3. 对应的头文件:string.h。

        我们来看一个示例:

8.strncat的使用

        strncat函数的原型如下:

char* strncat (char* destnation, const char* source, size_t num);
  1. 将源字符串的前num个字符追加到目标字符串的后面,再追加一个'\0'。
  2. 如果源字符串的长度小于num,只会将源字符串中从左到'\0'的内容追加到目标字符串的后面。
  3. 对应的头文件是:string.h。

        我们来看一个示例:

9.strncmp的使用

        strncmp函数的原型如下:

int strncmp (const char* str1, const char* str2, size_t num);
  1. 比较2个字符串的前num个字符。
  2. 逐个往后比较字符的ASCII码值,直到遇到不相同的字符或'\0'。
  3. 大于则返回一个大于0的数,小于则返回一个小于0的数。如果所有字符都相同,则返回0。
  4. 对应的头文件是:string.h。           

        我们来看一个示例:

10.strstr的使用和模拟实现

        strstr函数的原型如下:

版本1:
const char* strstr (const char* str1, const char* str2);
版本2:char* strstr (      char* str1, const char* str2);
  1. 在str1字符串中去找str2字符串。如果找到了,就返回这个字符串在str1中的起始地址,如果没找到,返回空指针。
  2. 如果多次出现,找的是第一次出现的位置。
  3. 对应的头文件:string.h。 

        我们来看一个示例:

        我们再来看一下它的模拟实现:

        上面的代码是一个常规的模拟实现,结合画图会更好理解。

        关于字符串查找,有一种算法叫做KMP算法,特点是高效,但代码比较难以理解。

11.strtok函数的使用

        strtok函数的原型如下:

char* strtok (char* str, const char* sep);    

        以字符串"abcd@qq.com"为例,如果我们不想看到'@'和' . '这些分隔符,而是想要提取出abcd、qq和com这些内容。我们就可以使用strtok函数,请看下面的解释:

  1. 第一个参数str,就是传入字符串"abcd@qq.com"。
  2. 不过,为了不修改原来的字符串,我们一般把原字符串的内容拷贝到另一个变量中,用这个临时变量来传参。比如:char tmp[20] = {0}; strcpy(tmp, "abcd@qq.com");
  3. sep参数是一个字符串,里面包括了我们需要去掉的分隔符,如:const char* sep = "@.";
  4. 第一次调用strtok函数:strtok(tmp, sep);,此时tmp变为:"abcd\0qq.com",函数会返回a的地址,把这个地址传入printf,可以打印出abcd。
  5. 刚刚调用strtok函数时,函数找到了第一个标记:@,将其变为\0,并保存了这个位置,下一次调用的时候,就会从这个位置开始往后查找下一个标记。
  6. 第二次调用strtok函数:strtok(NULL, sep);,此时tmp变为:"abcd\0qq\0com",函数会返回q的地址,把这个地址传入printf,可以打印出qq。
  7. 刚刚调用strtok函数时,函数找到了第二个标记:. ,将其变为\0,并保存了这个位置,下一次调用的时候,就会从这个位置开始往后查找下一个标记。
  8. 第三次调用strtok函数:strtok(NULL, sep);,没有找到标记,tmp不变,函数返回c的地址,把这个地址传入printf,可以打印出com。
  9. 如果继续调用,已经找不到更多的标记了,函数会返回NULL。
  10. 对应的头文件:string.h。

        我们来看一个示例:

        当然了,上面的代码不够普适,如果我们不知道字符串中到底有多少个分隔符,也就不知道应该调用多少次,那该怎么办呢?请看代码:

12.strerror函数的使用

        strerror函数的原型如下:

char* strerror (int errnum);
  1. 在不同的系统和C语言标准库中,都规定了一些错误码,一般是放在errno.h这个头文件中进行说明。 
  2. C语言程序在启动的时候,就会使用一个全局变量errno来记录当前程序的错误码。
  3. 如果想使用全局变量errno,需要包含对应的头文件:errno.h。
  4. 程序刚启动的时候,errno是0,表示没有错误。
  5. 当我们在使用库函数的时候,如果发生了某种错误,就会将对应的错误码放在errno中。
  6. 每一个错误码的数字,都是整数,代表了不同的错误信息。
  7. strerror函数就可以将错误码所对应的错误信息的字符串起始地址返回。
  8. strerror的使用需要包含对应的头文件:string.h。

        我们来看看一些错误码对应的错误信息:

        我们来看看strerror函数的应用:

        我们还可以了解一下perror函数,相当于printf + strerror的作用,可以直接将错误信息打印出来,还可以传入一个参数,额外加上一个字符串:


完结

http://www.lryc.cn/news/619598.html

相关文章:

  • 一个接口多个实现类,如何动态调用
  • 长篇音频制作(小说自动配音)完整教程
  • 15.卷积神经网络
  • 【题解】[CQOI2006] 洛谷P4196 凸多边形 /【模板】半平面交
  • 钻井泥浆搅拌机的设计cad1张三维图+设计说明书
  • 【Abp.VNext】Abp.Vnext框架模块学习
  • 服务器如何应对SYN Flood攻击?
  • 如何管理需求文档的版本历史
  • 【嵌入式电机控制#31】FOC:霍尔安装误差的补偿
  • MyBatis 中 XML 与 DAO 接口的位置关系及扫描机制详解
  • 深度学习——03 神经网络(2)-损失函数
  • Flutter网络请求实战:Retrofit+Dio完美解决方案
  • 51单片机-51单片机最小系统
  • 区块链DApp:颠覆未来的去中心化应用
  • 性能优化之通俗易懂学习requestAnimationFrame和使用场景举例
  • PyTorch生成式人工智能——基于Transformer实现文本转语音
  • 浅谈TLS 混合密钥交换:后量子迁移过渡方案
  • [TG开发]简单的回声机器人
  • 科技赋能虚拟形象:3D人脸扫描设备的应用与未来
  • vscode+phpstudy+xdebug如何调试php
  • 【R语言】R语言的工作空间映像(workspace image,通常是.RData)详解
  • YOLO v1 输出结构、预测逻辑与局限性详解
  • 教育元宇宙:一场重构教育生态的数字革命
  • 在实验室连接地下车库工控机及其数据采集设备
  • 面向局部遮挡场景的目标检测系统设计与实现
  • 开源WAF新标杆:雷池SafeLine用语义分析重构网站安全边界
  • Go语言实战案例:使用Gin处理路由参数和查询参数
  • .net\c#web、小程序、安卓开发之基于asp.net家用汽车销售管理系统的设计与实现
  • Redis学习——Redis的十大类型String、List、Hash、Set、Zset
  • SQL详细语法教程(一)--数据定义语言(DDL)