C语言进阶【1】--字符函数和字符串函数【1】
本章概述
- 字符分类函数
- 字符转换函数
- strlen的使用和模拟实现
- strcpy的使用和模拟实现
- strcat的使用和模拟实现
- strcmp的使用和模拟实现
- 彩蛋时刻!!!
字符分类函数
- 字符: 这个概念,我们在以前的文章中讲过了。我们键盘输入的信息都是字符。字符大体可以分为两类——单个字符,字符串。而单个字符又可以进行分类——字母字符,数字字符,特殊字符和不可见字符。进行思维图展示:

在日常生活中,我们写的字符也就是随便写,比如,123,abc……。但在C语言中,为了识别出字符和字符串,我们就要用两个操作符——' '和" "。' '是用来识别单个字符的," "是用来识别字符串的。
我们对于所写的字符,我们人都能识别出来。A我们能识别它是大写,a我们能识别它是小写,1我们能识别它是数字。但是,计算机是无法识别出来的,所以,为了能够让计算机识别,我们就创建了字符分类函数。我们进行展示:
它们的头文件是:<ctype.h>,当条件为真时,就会返回大于0的数值,反之返回小于0的数值。这些字符分类函数的用法都是相同,所以我们举一个就行了(常用的),比如,islower判断是否小写的函数。我们先来看它的类型和参数:
// int islower (int c)
进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <ctype.h>
int main()
{int c = islower('a');int b = islower('A');if (c > 0)printf("%c是小写\n", 'a');elseprintf("%c是大写\n", 'a');if (b > 0)printf("%c是小写\n", 'A');elseprintf("%c是大写\n", 'A');return 0;
}
结果运行图:
对于其它字符分类函数的使用,大家可以点击连接进行学习使用:https://cplusplus.com/reference/clibrary/
字符转换函数
C语言中就俩字符转换函数,它们的头文件是 <ctype.h>,如下:
// 大写转小写:int tolower (int c)
// 小写转大写:int toupper (int c)
进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main()
{int c = toupper('a'); //转大写printf("%c\n", c);int b = tolower('A'); //转小写printf("%c\n", b);return 0;
}
结果运行图:
我们来写个程序,运用我们所学的知识:
// 我们写一句英文,然后,把我们所写的英文全部转换为大写,比如:
// I am a student.-------> I AM A STUDENT.
// 我们来写两个方法进行实现。
程序【1】
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main()
{char arr[] = "I am a student.";int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;printf("转换前:%s\n", arr);for (i = 0; i < sz; i++){if (islower(arr[i]))arr[i] = arr[i] - 32; //大写字母的AS||值比小写字母的AS||值少32}printf("转换后:%s\n",arr);return 0;
}
结果运行图:
程序【2】。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <ctype.h>
int main()
{char arr[] = "I am a student.";int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;printf("转换前:%s\n", arr);for (i = 0; i < sz; i++){if(islower(arr[i]))arr[i]=toupper(arr[i]); //使用 toupper进行转换}printf("转换后:%s\n",arr);return 0;
}
结果运行图:
大家也可以进行举一反三,比如,大写转小写代码。
strlen的使用和模拟实现
- strlen的使用:后面,我们要开始讲字符串相关的函数了,它们的头文件<string.h>。前面,咱们已经讲过了
strlen的使用和模拟实现,今天在复习一下。我们知道,每个字符串后面都会自动补\0,strlen统计的是\0之前的字符串的长度。进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%zd", strlen(arr));return 0;
}
结果运行图:
对于strlen的返回值打印最好要用%zd。因为strlen的返回值类型为size_t(无符号整形),关于为什么是size_t的类型,咱们在以前的文章中讲过了。
我们还可以指定它的统计起始位置,进行代码展示:下面展示一些 内联代码片。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%zd", strlen(arr+1)); //从b开始进行统计,所以统计数为:5.return 0;
}
结果运行图展示:
- strlen的模拟:
// 咱们写三种方法进行实现。
// 思路:统计\0之前的字符数。
方法【1】----计数器的方式
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
size_t my_strlen(char arr[])
{int count = 0;int i = 0;while (arr[i]){count++;i++;}return count;
}
int main()
{char arr[] = "abcdef";printf("%zd\n", my_strlen(arr));return 0;
}
结果运行图:
方法【2】----指针-指针
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
size_t my_strlen(char arr[])
{char*s1=arr;while (*arr){arr++;}return arr-s1;
}
int main()
{char arr[] = "abcdef";printf("%zd\n", my_strlen(arr));return 0;
}
结果运行图:
方法【3】----递归函数
进行如图所示的逻辑:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
size_t my_strlen(char arr[])
{if (*arr){arr++;return 1 + my_strlen(arr);}elsereturn 0;}
int main()
{char arr[] = "abcdef";printf("%zd\n", my_strlen(arr));return 0;
}
结果运行图:
在这三种方法都很好,都是使用了我们所学过的知识,大家要掌握。
strcpy的使用和模拟实现
- strcpy的使用: 具有拷贝字符串的功能。比如,A字符串拷向B字符串,B字符串拷向A字符串,自己向自己拷贝。 我们来看它的结构组成:
// char * strncpy ( char * destination, const char * source );| | || | || | |
返回的是des的地址(未更改前的) 目的地的地址 拷贝源的地址// 因为我们不想拷贝来源的时候,发生更改,所以用const修饰。
- 它的使用有几个要注意的点:
- 1.拷贝的来源必须以
' \0'结尾。 - 2.dest的空间要足够大,要容的下要拷贝的内容。
- 3.des的空间是要可修改的,要不然就无法拷贝。
- 4 .拷贝的时候,也会把source的
' \0'拷贝过去。 - 5.拷贝的起始位置是可以指定的(des和source都可以指定起始位置,指定的方式和strlen一样)
- 1.拷贝的来源必须以
- 进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcedf";char arr1[30]={0};printf("拷贝前arr1:%s\n",arr1);printf("拷贝后arr1:%s\n", strcpy(arr1, arr));return 0;
}
结果运行图:
- strcpy的模拟实现:
// 遇到source的' \0'就会拷贝停止,但也要把' \0'拷贝过去
进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* des, const char* str)
{char* p = des; //因为经过后面的程序后,des的值早变了,所以要先给cpy一份assert(des && str); //判断一下,des和str是否为空指针while (*des++=*str++){;}return p;
}
int main()
{char arr[] = "abcedf";char arr1[30] = {0};printf("拷贝前arr1:%s\n",arr1);printf("拷贝后arr1:%s\n", my_strcpy(arr1, arr));return 0;
}
结果运行图:
strcat的使用和模拟实现
- strcat的使用:它具有在字符串的后面补上别的字符串的功能。比如:
// char arr[30]="abd" ;
// char arr1[4]="acd" ;
// arr1向arr的末尾补齐------->"abdacd"
- 它的结构所示:
// char * strcat(char *dest, const char*src)
// 返回值和每个参数的意思和strcpy是一样的
- 它的使用要注意的点:
- 1.
src会找到des的第一个出现的' \0',在此处把src的字符串补充到des中(此时的’ \0’会被覆盖)。 - 2 .由于des的’ \0’被覆盖了,所以str在补充字符串后,会在末尾添加’\0’。(占别人的东西,最后肯定要还的!)
- 3.des的空间要够大,要容得下补充后的字符空间。
- 4 .补充的起始位置是可以指定的(des和str都可以指定起始位置,指定的方式和strlen一样)
- 1.
- 进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{char arr[30] ="abcdef";char arr1[] = "xxx";printf("%s\n", strcat(arr, arr1));return 0;
}
结果运行图:
- strcat的模拟实现:思路:我们要找到des的’\0’, 才能进行补充。进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* des, const char* str)
{char* p = des;assert(des && str);while (*des)des++;while (*des++=*str++){;}return p;
}
int main()
{char arr[30] ="abcdef";char arr1[] = "xxx";printf("%s\n", my_strcat(arr, arr1));return 0;
}
结果运行图:
strcmp的使用和模拟实现
- strcmp的使用:是用来比较字符串的大小的。它比较的可不是两个字符串的长度大小,比较的是每单个字符的大小(就是比较两个单个字符的AS||值的大小)。结构组成如下:
// int strcmp (const char * str1, const char * str2)
- 要注意的几点:
- 1.比较的顺序就是所输入的数据,比如,输入顺序:str1 ,str2。 比较顺序:str1 ,str2。 输入顺序:str2 ,str1。 比较顺序:str2 ,str1。
- 2 .str1 > str2就会返回大于0的数值。str1<str2就会返回小于0的值。str1=str2就会返回0。
- 3.因为我们要比较两个字符串的大小,所比较的内容不能被更改,所以参数要用const修饰。
- 4 .比较的起始位置是可以指定的(str1和str2都可以指定起始位置,指定的方式和strlen一样)
- 进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{char arr[30] ="abcdef";char arr1[] = "abx";printf("%d\n", strcmp(arr, arr1));return 0;
}
结果运行图:
大家可自行试一下,对于和等于的代码。
- strcmp的模拟实现:比较的AS||值的大小,进行代码展示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <string.h>
int my_strcmp(const char* e1, const char* e2)
{while (*e1 == *e2){e1++;e2++;if (*e1 == '\0' || *e2 == '\0')break;}return *(int*)e1 - *(int*)e2;
}
int main()
{char arr[30] = "abcdef";char arr1[] = "abx";printf("%d\n", my_strcmp(arr, arr1));return 0;
}
结果运行图:
彩蛋时刻!!!
https://www.bilibili.com/video/BV1Ze4y1F7CV/?spm_id_from=333.337.search-card.all.click
每章一句:总有人翘首以盼为你而来。感谢你能看到这里,点赞+关注+收藏+转发是对我最大的鼓励,咱们下期间!!!
相关文章:
C语言进阶【1】--字符函数和字符串函数【1】
本章概述 字符分类函数字符转换函数strlen的使用和模拟实现strcpy的使用和模拟实现strcat的使用和模拟实现strcmp的使用和模拟实现彩蛋时刻!!! 字符分类函数 字符: 这个概念,我们在以前的文章中讲过了。我们键盘输入的…...
git提交自动带上 Signed-off-by信息
为了确保在使用 Signed-off-by 签名的同时保留你的提交消息,你需要修改 prepare-commit-msg 钩子脚本,以便它不会丢失原始的提交信息。 增加prepare-commit-msg 钩子以保留提交消息 prepare-commit-msg 钩子的目的是在提交信息文件中插入额外的内容&am…...
图论(2)
一、度 度统计的是一个节点上又多少条边 度出度入度 出度:统计以该节点为起始点箭头指向外面的边的条数 入度:统计箭头指向该节点的边数 度为1的节点为悬挂节点,边为悬挂边 用矩阵计算节点的度 二、握手定理 比如这里第一个集合里面有三…...
ASP.NET Core 入门教学十九 依赖注入ioc
ASP.NET Core内置了对依赖注入(Dependency Injection,简称DI)的支持,这是一种设计模式,用于实现控制反转(Inversion of Control,简称IoC),从而使得应用程序组件之间的耦合…...
omm kill 内存碎片化
内存频繁 OOM(Out of Memory)会导致内存碎片化,并进一步加剧无可用内存分配的问题。碎片化是内存管理中常见的问题,当系统频繁分配和释放内存时,内存空间会被分割成许多小块,虽然内存总量可能足够,但这些小块无法满足较大进程或数据的内存需求,最终导致系统无法找到足够…...
JS中给元素添加事件监听器的各种方法详解(包含比较和应用场景)
JavaScript 中给元素添加事件监听器的各种方法详解 在 JavaScript 中,事件处理是前端开发的一个重要部分。无论是点击按钮、提交表单,还是鼠标悬停,都涉及到事件监听。本文中,我将详细讲解各种给元素添加事件监听器的方法&#x…...
Python基本数据类型之复数complex
来源: “码农不会写诗”公众号 链接:Python基本数据类型之复数complex 文章目录 01 基本概念02 基本运算03 拓展1复数与向量 复数complex Python基本数据之复数(complex)即包含实部和虚部的数字。 01 基本概念 即包含实部和虚部的数字。 在Python中&am…...
第六届机器人与智能制造技术国际会议 (ISRIMT 2024)
目录 会议详情 主题 会议官网 会议详情 第六届机器人与智能制造技术国际研讨会(ISRIMT 2024)计划于2024年9月20-22日在常州举行。会议主要聚焦“机器人”和“智能制造技术”的研究领域,旨在为机器人和智能制造技术领域的专家学者、工程技术…...
鸿蒙轻内核M核源码分析系列十九 Musl LibC
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 轻内核M核源码分析系列一 数据结构-双向循环链表 轻内核M核源码分析系列二 数据结构-任务就绪队列 鸿蒙轻内核M核源码分析系列三 数据结构-任务排序链表 轻…...
mysqldump备份恢复数据库
mysqldump程序可以用来备份和恢复数据库 ,默认情况mysqldump会创建drop table, create table,和insert into的sql语句. 语法 > mysqldump [options] db_name [tbl_name ...] > mysqldump [options] --databases db_name ... > mysqldump [options] --all-databases备…...
路径规划——RRT算法
路径规划——RRT算法 算法原理 RRT算法的全称是快速扩展随机树算法(Rapidly Exploring Random Tree),它的思想是选取一个初始点作为根节点,通过随机采样,增加叶子节点的方式,生成一个随机扩展树,当随机树中的叶子节点…...
OPCUA-PLC
下载opcua服务器(有PLC可以直连),UaAnsiCServer下载路径 双击运行如下,Endpoint显示opcua服务路径 opc.tcp://DESKTOP-9SD7K4B:48020 下载opcua客户端(类似编写代码连接操作),UaExpert下载路径 如果连接失败,有一个授权认证,点击同意就行 java代码实现连接opcUA操作 pom.…...
在Windows系统上部署PPTist并实现远程访问
在Windows系统上部署PPTist并实现远程访问 前言PPTist简介本地部署PPTist步骤1:获取PPTist步骤2:安装依赖步骤3:运行PPTist 使用PPTist远程访问PPTist步骤1:安装Cpolar步骤2:配置公网地址步骤3:配置固定公网…...
【Grafana】Prometheus结合Grafana打造智能监控可视化平台
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
隐私计算实训营:SplitRec:当拆分学习遇上推荐系统
拆分学习的概念 拆分学习的核心思想是拆分网络结构。每一个参与方拥有模型结构的一部分,所有参与方的模型合在一起形成一个完整的模型。训练过程中,不同参与方只对本地模型进行正向或者反向传播计算,并将计算结果传递给下一个参与方。多个参…...
存在nginx版本信息泄露(请求头中存在nginx中间件版本信息)
在Nginx的配置文件中,server_tokens指令用于控制Nginx在HTTP响应头中包含的服务器版本信息,默认为true,开启状态。当设置为off时,Nginx将不会在响应头中包含任何服务器版本信息,仅显示“Server: nginx”这一行…...
在js中观察者模式讲解
在JavaScript中,观察者模式(Observer Pattern)是一种设计模式,允许一个对象(被观察者,Subject)维护一个依赖它的对象列表(观察者,Observer),并在它自身状态发生变化时自动通知这些观察者。观察者模式的典型使用场景包括事件系统、数据绑定和实时更新等情况。 一 、…...
java常用面试题-基础知识分享
什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法…...
iOS——runLoop
什么是runloop RunLoop实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行相应的处理逻辑。线程执行了这个函数后,就会处于这个函数内部的循环中,直到循环结束,函数返回。 RunLoo…...
python: 多模块(.py)中全局变量的导入
文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块&…...
文章三:Elasticsearch 集群恢复和索引分布
集群恢复网关与集群索引分布必要性了解在 Elasticsearch(简称 ES)集群运维中,集群重启恢复、残余索引处理、索引分片分布是保障集群稳定性、数据完整性、读写性能的三大核心基础能力。多数集群故障、数据丢失、分片异常、读写卡顿问题&#x…...
别再乱装驱动了!Win10/Win11频繁蓝屏DPC_WATCHDOG_VIOLATION,用WinDBG揪出真凶(保姆级排查流程)
彻底解决Win10/Win11蓝屏噩梦:DPC_WATCHDOG_VIOLATION实战排查指南每次看到那个蓝色屏幕突然出现,心跳都会漏掉一拍——特别是当重要文件还没来得及保存的时候。DPC_WATCHDOG_VIOLATION(错误代码133)堪称Windows系统最令人头疼的蓝…...
告别美术字烦恼!Unity UGUI自定义字体工具一键打包全流程(附避坑指南)
告别美术字烦恼!Unity UGUI自定义字体工具一键打包全流程(附避坑指南)在游戏UI开发中,美术字体往往是提升视觉表现力的关键元素。然而,从设计稿到最终在Unity中完美呈现,这条路上布满了各种"坑"&…...
HexStrike AI v6.0:面向红队实战的多智能体渗透框架
1. 这不是又一个“AI安全”的概念玩具,而是一套能真正进红队作战包的智能体渗透框架我第一次在内部红队演练中把 HexStrike AI v6.0 推进真实靶场时,没敢直接叫它“AI渗透工具”——怕被老队员当场笑出声。毕竟过去三年里,我亲手试过七套标榜…...
贝叶斯网络中条件独立性的判断 CS188 Note13 学习笔记
更好的阅读体验 D-Separation D-separation 是贝叶斯网络中的一个概念,用于通过图结构DAG随机变量之间的条件独立性 首先需要回顾一下的是:在图中,只要给定了某个节点的所有父节点,那么该节点就与其所有祖先节点在逻辑上是相互独…...
有些女的就是只配孤独终老,一说话就伤人,我觉得没有必要相处,没必要去改变一些人,林子大了,什么鸟都有。。。——拉开距离,减少纠缠,建立边界,降低期待
你现在这种反感,更多像是长期被消耗后的失望和厌倦。 当一个人长期经历: 被否定 不被维护 说话被刺 情绪被压着 沟通没反馈 确实很容易慢慢变成: “我不想再理解了,也不想再靠近了。” 这其实是一种心理上的“抽离”。 不过也要注意,别因为遇到一种人,就把情绪扩大…...
Nacos CVE-2021-29442:Spring Boot Actuator未授权访问漏洞深度解析
1. 这个漏洞不是“改个配置就能修好”的那种 Nacos CVE-2021-29442,这个名字在2021年中后期的Java中间件运维圈里,曾让不少团队在凌晨三点被电话叫醒。它不是那种需要你翻文档、查API、调参数的常规问题,而是一个典型的“默认行为埋雷”——…...
3步构建物联网数字孪生:Eclipse Ditto实战指南
3步构建物联网数字孪生:Eclipse Ditto实战指南 【免费下载链接】ditto Eclipse Ditto™: Digital Twin framework of Eclipse IoT - main repository 项目地址: https://gitcode.com/gh_mirrors/ditto6/ditto 在物联网(IoT)时代,如何高效管理成千…...
【DeepSeek数据隐私保护终极指南】:20年安全专家亲授5大合规落地实践与3大避坑红线
更多请点击: https://codechina.net 第一章:DeepSeek数据隐私保护的核心理念与演进脉络 DeepSeek自诞生以来,将“数据主权归用户、模型能力不以隐私让渡为前提”确立为不可妥协的底层信条。其隐私保护理念并非静态规范,而是随技术…...
Python爬虫绕过JA3/JA4指纹检测的TLS定制实战
1. 这不是“绕过检测”,而是理解TLS握手的底层语言你写好了一个Python爬虫,目标网站明明没上WAF、也没用Cloudflare,但一发请求就返回403——连HTML正文都没有,只有个空响应体。抓包一看,服务器在TCP三次握手之后、TLS…...
