C语言(字符函数和字符串函数)1

                       Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~     

                        💥个人主页:小羊在奋斗

                        💥所属专栏:C语言   

        本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。 

                                1、字符分类函数

                                2、字符转换函数

                                3、strlen 的使用和模拟实现

                                4、strcpy 的使用和模拟实现

                                5、strcat 的使用和模拟实现

1、字符分类函数

        C语言中有一些专门作字符分类的函数,使用这些函数需要包含头文件 ctype.h

isalnum

检查一个字符是否是字母或数字
(函数)

isalpha

检查一个字符是否是字母
(函数)

islower

检查一个字符是否是小写字母
(函数)

isupper

检查一个字符是否是大写字母
(函数)

isdigit

检查字符是否为数字
(函数)

isxdigit

检查一个字符是否是十六进制的字符
(函数)

iscntrl

检查一个字符是否是控制字符
(函数)

isgraph

检查一个字符是否是图形字符
(函数)

isspace

检查一个字符是否是空白字符
(函数)

isblank

(C99)

检查一个字符是否是空格字符
(函数)

isprint

检查一个字符是否是可打印字符
(函数)

ispunct

检查一个字符是否是标点字符

        更多详细内容请点击跳转阅读 —> C 标准库头文件 - cppreference.com 


        这些函数的使用方法、返回值等基本是一致的,这里就以 islower 函数为例,写一个将字符串中非大写的字母转化为大写字母的示例。

 

 2、字符转换函数

        C语言中有两个实现大小写转换的函数,tolower将大写字母转小写) 和 toupper将小写字母转大写)。

        那既然有了这两个函数,上面将字符串中的小写字母转换为大写字母的代码就可以简化一下了。

 

3、strlen 的使用和模拟实现

        3.1 strlen 的返回值

        strlen 函数我们已经非常的熟悉,之前也介绍了两种模拟 strlen 函数的方法,这里再关于strlen 的使用做一些补充,同时再介绍另一种 strlen 的模拟实现方法。

        

        以前我们在使用 strlen 函数的时候,可能没有细心地关注过 strlen 的返回值类型,有时候我们使用 int 类型来接收它的返回值好像也没出现什么问题,但其实这是一个很值得我们去注意的一个问题。来看下面的示例:

        按道理来说-3小于0应该打印的是“<=”,但结果却并不是。其中的原因就在于 strlen 的返回值类型是 size_t 类型,两个 size_t 类型的值相减还是 size_t 类型,而我们知道整型是以补码的形式存储的,所以 size_t 类型会把-3的补码当做一个很大的正整数,这个数当然是大于0的,所以结果是打印出了 “>”。而如果我们想让它输出我们想要的结果,只需要强制类型转换就行。

        3.2 strlen 的模拟实现 

         之前的文章中我们用了指针遍历数组和指针-指针两种方法来模拟 strlen 函数,这里我们再使用另一种方法来模拟实现——递归。

#include <stdio.h>
#include <assert.h>size_t my_strlen(char* str)
{assert(str != NULL);if (*str != '\0'){return 1 + my_strlen(++str);}else{return 0;}
}int main()
{char str[] = "Are you ok?";size_t len = my_strlen(str);printf("%zd\n", len);return 0;
}

        我们之前说过,递归就是一个把大事化小的过程,适合于解决一些简单重复的操作,就像上面重复读取一个字符并判断的过程。这个方法很简单,一眼就能明白其中的原理,我就不过多阐述了。值得一说的是,这个方法并没有创建新变量,这是区别于前两种方法的地方。 

4、strcpy 的使用和模拟实现

        4.1 strcpy 的用法 

        strcpy 是一个字符串拷贝函数,它的作用是把第二个参数所指的字符串拷贝给第一个参数所指的字符串数组中,注意不要搞反了。

        更多详细介绍请点击查阅 —> strcpy, strcpy_s - cppreference.com

         

        使用 strcpy 也需要包含头文件 <string.h>,是比较简单的,但是有几个需要特别注意的点。 

(1)源字符串必须以 ‘\0’ 结束;

        就像 strlen 函数一样,strcpy 函数也需要知道它应该在哪里停止拷贝。 

(2)会将源字符串中的 ‘\0’ 拷贝到目标空间;

         在上面的代码中我们使用 strlen 函数证明了这点。

(3)目标空间必须足够大,以确保能放得下字符串;

        以上面的代码为例,如果我们定义的字符数组 str2 太小,程序就会出错。

  

(4)目标空间必须可修改。

         这里举个反例来证明这一点。

        将常量字符串 “abc” 存到字符指针变量 ps 中,前面说过常量字符串是不能被修改的,所以程序就出错了。 

        4.2 strcpy 的模拟实现 

        就像 strlen 函数一样,我们同样也可以模拟实现一个 strcpy 函数,完成字符串拷贝的功能。 

#include <stdio.h>
#include <assert.h>
#include <string.h>void my_strcpy(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);while (*sour != '\0'){*dest = *sour;sour++;dest++;}*dest = *sour;//\0
}int main()
{char str1[] = "what can I say? man.";char str2[50] = { 0 };my_strcpy(str2, str1);printf("%s\n", str2);printf("%zd\n", strlen(str2));return 0;
}

        逻辑也是特别简单的,只不过我们要特别注意字符 ‘\0’ 也需要拷贝过去。

        4.3 strcpy 的返回值 

        关于 strcpy 函数我们可能会忽略了它的返回值,因为我们会觉得这个函数并不需要什么返回值,但其实它是有返回值的,既然有返回值,那它的返回值就有用,所以严格来说我们上面模拟实现的 strcpy 函数返回值应该为 char * 而不是 void 。strcpy 函数返回的是目标字符串的首地址,这使得 strcpy 可以链式操作。

        所以上面的代码可以更新为:

#include <stdio.h>
#include <assert.h>
#include <string.h>char* my_strcpy(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);char* pd = dest;while (*sour != '\0'){*dest = *sour;sour++;dest++;}*dest = *sour;//\0return pd;
}int main()
{char str1[] = "what can I say? man.";char str2[50] = { 0 };char* ps = my_strcpy(str2, str1);printf("%s\n", ps);printf("%s\n", my_strcpy(str2, str1));printf("%zd\n", strlen(str2));return 0;
}

        4.4 strcpy 模拟实现的优化 

        虽然我们已经完成了 strcpy 函数的模拟实现,但上面的代码还可以优化。因为字符‘\0’的特殊,上面的代码中我们是将普通字符和‘\0’字符分开处理的,那是否可以有个办法将这两步合在一起呢?

        来体会下面这条代码:

        我们用一条代码就实现了拷贝字符串,包括拷贝字符‘\0’。其中的原理也是非常简单,当字符‘\0’拷贝到目的空间后,括号中表达式的值为0,就自动跳出了循环。需要说明的是两个指针变量都是先解引用,然后再自增的。

5、strcat 的使用和模拟实现

         5.1 strcat 的用法

        strcat 函数的作用是将源字符串拼接到目标字符串的后面,跟 strcpy 函数类似,strcat 是将第二个参数所指的字符串拼接到第一个参数所指的字符串后面。

        更多详细的介绍请点击阅读 —> strcat, strcat_s - cppreference.com

        同样的,strcat 函数也有几个需要注意的点: 

        (1)源字符串必须以‘\0’结束;

        (2)目标字符串中也得有‘\0’,否则没法知道拼接在哪里;

        (3)目标空间必须足够大;

        (4)目标空间必须可修改。

        5.2 strcat 的返回值

        类比 strcpy,strcat 也是有返回值的,并且返回值也是目标字符串的首地址。

        5.3 strcat 的模拟实现

        我们依然可以自己写一个函数来模拟实现 strcat 的功能,方法很简单,类似于模拟实现 strcpy 的方法,我们只需要想办法将源字符串拼接到目标字符串末尾就行,相信对于现在有点基础的我们来说这并不是什么难事。

#include <stdio.h>
#include <assert.h>char* my_strcat(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);char* pd = dest;while (*dest++);dest--;//覆盖掉目标字符串中的\0while (*dest++ = *sour++);return pd;
}int main()
{char str1[20] = "hello ";char str2[] = "world";char *ps = my_strcat(str1, str2);printf("%s\n", ps);return 0;
}

        上面我们是将一个字符串与另一个字符串拼接在一起,那能不能将一个字符串拼接到自己的末尾呢?

        可以看到,用我们自己写的函数不能实现字符串自己拼接到自己后面,这是因为拼接的过程是在目标字符串末尾的 ‘\0’ 处开始拼接的,也就是说目标字符串的第一个字符会覆盖掉它自己末尾的 ‘\0’,那函数的第二个参数指针就永远也找不到 ‘\0’ 以结束拼接,就会陷入死循环。

        但是 strcat 函数可以,不过 strcat 函数并不能保证这件事情,也就是说上面能成功是偶然的。 

           如果觉得我的文章还不错,请点赞、收藏 + 关注支持一下,我会持续更新更好的文章。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/19491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python API自动化(接口测试基础与原理)

1.接口测试概念及应用 什么是接口 接口是前后端沟通的桥梁&#xff0c;是数据传输的通道&#xff0c;包括外部接口、内部接口,内部接口又包括&#xff1a;上层服务与下层服务接口&#xff0c;同级接口 外部接口&#xff1a;比如你要从 别的网站 或 服务器 上获取 资源或信息 &a…

SpringMVC框架学习笔记(四):模型数据 以及 视图和视图解析器

1 模型数据处理-数据放入 request 说明&#xff1a;开发中, 控制器/处理器中获取的数据如何放入 request 域&#xff0c;然后在前端(VUE/JSP/...)取出显 示 1.1 方式 1: 通过 HttpServletRequest 放入 request 域 &#xff08;1&#xff09;前端发送请求 <h1>添加主人…

基于RNN和Transformer的词级语言建模 代码分析 _generate_square_subsequent_mask

基于RNN和Transformer的词级语言建模 代码分析 _generate_square_subsequent_mask flyfish Word-level Language Modeling using RNN and Transformer word_language_model PyTorch 提供的 word_language_model 示例展示了如何使用循环神经网络RNN(GRU或LSTM)和 Transforme…

【AI大模型】如何让大模型变得更聪明?基于时代背景的思考

【AI大模型】如何让大模型变得更聪明 前言 在以前&#xff0c;AI和大模型实际上界限较为清晰。但是随着人工智能技术的不断发展&#xff0c;基于大规模预训练模型的应用在基于AI人工智能的技术支持和帮助上&#xff0c;多个领域展现出了前所未有的能力。无论是自然语言处理、…

JavaScript的垃圾回收机制

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、垃圾…

匹配字符串

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python提供了re模块&#xff0c;用于实现正则表达式的操作。在实现时&#xff0c;可以使用re模块提供的方法&#xff08;如search()、match()、finda…

信息系统项目管理师0603:项目整合管理 — 考点总结(可直接理解记忆)

点击查看专栏目录 文章目录 项目整合管理 — 考点总结(可直接理解记忆) 输入、输出、工具和技术 历年考题直接考输入,输出、工具和技术的有17年11月第34、35,19年5月第34、35,20年11月27、28,21年5月第26,28,21年11月第28,22年5月第25,22年11月第22考题 项目章程是正…

CasaOS玩客云安装全平台高速下载器Gopeed并实现远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于Python的酒店客房入侵检测系统的设计与实现

基于Python的酒店客房入侵检测系统的设计与实现 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 酒店客房入侵管理界面 结合上文的结构搭建和用户需求&#xff0c;酒店客房入侵检测系统的…

【Unity Shader入门精要 第12章】屏幕后处理效果(一)

1. 原理和过程 屏幕后处理是绑定摄像机的&#xff0c;通过抓取当前摄像机渲染的图像作为 SrcTextrue&#xff0c;然后按需依次调用处理接口&#xff0c;对 SrcTexture 进行处理&#xff0c;最后将处理完成的 DstTexture 显示到屏幕上&#xff0c;整个过程的调度通过 C# 脚本完…

【机器学习】Adaboost: 强化弱学习器的自适应提升方法

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Adaboost: 强化弱学习器的自适应提升方法引言Adaboost基础概念弱学习器与强学习…

【蓝桥杯嵌入式】 第六届国赛

目录 题目 配置 注意事项 代码 - 默写大师 EEPROM读写函数 LED驱动函数 ADC采集 上电初始化 LCD 按键 PWM互补输出 全部代码 hardware.c hardware.h control.c control.h main.c 题目 配置 注意事项 复制LCD的工程&#xff0c;先配置资源 --- 勾选完选项一…

CCIG 2024:合合信息文档解析技术突破与应用前景

目录 背景当前大模型训练和应用面临的问题训练Token耗尽训练语料质量要求高LLM文档问答应用中文档解析不精准 合合信息的文档解析技术1. 具备多文档元素识别能力2. 具备版面分析能力3. 高性能的文档解析4. 高精准、高效率的文档解析文档多板式部分示例 文档解析典型技术难点元素…

案例|开发一个美业小程序,都有什么功能

随着移动互联网的迅猛发展&#xff0c;美业连锁机构纷纷寻求数字化转型&#xff0c;以小程序为载体&#xff0c;提升服务效率&#xff0c;增强客户体验。 线下店现在面临的困境&#xff1a; 客户到店排队时间过长&#xff0c;体验感受差 新客引流难&#xff0c;老用户回头客…

基于EV54Y39A PIC-IOT WA的手指数量检测功能开发(MPLAB+ADC)

目录 项目介绍硬件介绍项目设计开发环境及工程参考总体流程图硬件基本配置光照传感器读取定时器检测逻辑 功能展示项目总结 &#x1f449; 【Funpack3-2】基于EV54Y39A PIC-IOT WA的手指数量检测功能开发 &#x1f449; Github: EmbeddedCamerata/PIC-IOT_finger_recognition 项…

Flutter基础 -- Dart 语言 -- 注释函数表达式

目录 1. 注释 1.1 单行注释 1.2 多行注释 1.3 文档注释 2. 函数 2.1 定义 2.2 可选参数 2.3 可选参数 默认值 2.4 命名参数 默认值 2.5 函数内定义 2.6 Funcation 返回函数对象 2.7 匿名函数 2.8 作用域 3. 操作符 3.1 操作符表 3.2 算术操作符 3.3 相等相关的…

上海亚商投顾:沪指冲高回落 两市成交金额仅剩7000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日冲高回落&#xff0c;午后一度集体翻绿&#xff0c;临近尾盘小幅回升。光伏产业链再度走强&#…

aws 在ecs外部实例上运行gpu负载

参考资料 https://docs.amazonaws.cn/zh_cn/AmazonECS/latest/developerguide/ecs-gpu.htmlhttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/accelerated-computing-instances.html#gpu-instanceshttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/install-nvidia-drive…

LeetCode 63.不同路径Ⅱ

思路&#xff1a; 在有障碍物的地方增加一个判断即可 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int dp[105][105];int mobstacleGrid.size();int nobstacleGrid[0].size();for(int i0;i<m;i){for(int j0…

K8s集群之 存储卷 PV PVC

目录 默写 1 如何将pod创建在指定的Node节点上 2 污点的种类(在node上设置) 一 挂载存储​​​​​​​ 1 emptyDir存储卷 2 hostPath存储卷 ①在 node01 节点上创建挂载目录 ② 在 node02 节点上创建挂载目录 ③ 创建 Pod 资源 ④ 在master上检测一下&#xff1a;…