ctype.h的了解string.h库函数中各个函数的使用和模拟实现

目录

字符分类函数 

函数讲解 

使用样例

字符转换函数

函数讲解

使用样例

strlen的使用和模拟实现

strlen的使用

strlen的模拟实现

计数器

递归(不创建临时变量)

指针-指针

strcpy的使用和模拟实现

strcpy的使用

strcpy的模拟实现

strcat的使用和模拟实现

strcat的使用

strcat的模拟实现

strcmp的使用和模拟实现

strcmp的使用

strcmp的模拟实现

strstr的使用和模拟实现

strstr的使用

strstr的模拟实现

strncpy的使用和模拟实现

strncpy的使用

strncpy的模拟实现

strncat的使用和模拟实现

strncat的使用

strncat的模拟实现

strncmp的使用和模拟实现

strncmp的使用

strncmp的模拟实现


字符分类函数 

函数如果它的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车'\r',制表符'\t',或垂直制表符'\v'
isdigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或数字a~z,A~Z或0~9
ispunct标点符号,任何不属于数字或字母的图像字符(可打印符号)
isgraph任何图像字符
isprint任何可打印字符,包括图像字符和空白字符

函数讲解 

这些函数的使用方法都十分类似

int islower ( int c );

如果为假,函数会返回0,如果为真,函数会返回非零的值 

iscntrl用来判断一个字符是否为控制字符

isspace用来判断一个字符是否为空白字符

isdigit用来判断字符或者字符串是否为数字

islower用来判断一个字符是否为小写字母

isupper用来判断一个字符是否为大写字母

isalpha用来判断一个字符是否为字母

isalnum用来判断一个字符是否为字母或者数字

ispunct用来判断一个字符是否为标点符号

isgraph用来判断一个字符是否为图形字符

isprint用来判断一个字符是否是可打印的

图形字符如下:

使用样例

#include <stdio.h>
#include <ctype.h>int main()
{int i = 0;char str[] = "Hello World\n";char c;while (str[i]){c = str[i];if (islower(c))c -= 32;putchar(c);i++;}return 0;
}

 

这里首先要包含头文件 ctype.h

然后使用了库函数 islower用来判断字符是否为小写字母

如果字符为小写字母则将字符减去32改成大写字母

所以这个程序的作用是将字符串中所有的小写字母改成大写字母

字符转换函数

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

int tolower ( int c ); 
int toupper ( int c ); 

函数讲解

tolower可以将参数传进去的大写字母转小写

toupper可以将参数传进去的小写字母转大写

使用样例

#include <stdio.h>
#include <ctype.h>int main()
{int i = 0;char str[] = "Hello World\n";char c;while (str[i]){c = str[i];if (islower(c))c = toupper(c);putchar(c);i++;}return 0;
}

与上面近乎一致,只是将c -= 32变成了c = toupper(c)

两者的作用都相同,所以最终的结果也是一致的

strlen的使用和模拟实现

strlen的使用

该函数的作用是可以计算一个字符串的长度

也可以理解为计算'\0'之前出现的字符个数(不包含'\0')

这个长度最终以size_t函数的返回值形式出现(size_t为无符号整型)

我们只需要传一个字符串的起始地址给它即可(不一定是起始地址,从哪里传就从哪里开始计算)

#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello World";int ret = strlen(str);printf("%d\n", ret);return 0;
}

答案是由10个大小写字母和1个空白字符组成,所以答案是11

strlen的模拟实现

strlen的模拟实现有三种方法

计数器

#include <stdio.h>size_t my_strlen(const char* str)
{int count = 0;while (*str != '\0'){count++;str++;}return count;
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}

注:如果有str为什么可以str++的问题可以看我前面的博客中的const修饰变量

C语言:指针的基础详解-CSDN博客

这里使用了1个变量count计数,随着str的增加count一同增加,直到碰到'\0'就停止即可

递归(不创建临时变量)

#include <stdio.h>size_t my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}

这里使用递归逐渐增加str的位置,并且每递归一次就增加1,最终返回这个值即可

这个方法可以不需要创建临时变量

指针-指针

这里需要有一个知识点

两个同样类型的指针相减会得出它们之间元素的个数,以此得出第三个方法

#include <stdio.h>size_t my_strlen(const char* s)
{char* p = s;while (*p != '\0')p++;return p - s;
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}

多创建一个指针变量p让它走到'\0'之前,最后指针-指针即可

strcpy的使用和模拟实现

strcpy的使用

该函数的作用是可以将一个字符串的内容拷贝到另一个字符串中,以需要拷贝的字符串中的'\0'作为标志结束

注意:目标空间必需要足够大且可修改,不然会越界

strcpy的模拟实现

#include <stdio.h>char* my_strcpy(char* dest, const char* src)
{char* ret = dest;while (*dest++ = *src++);return ret;
}int main()
{char arr1[] = "abcdefg";char arr2[20];my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

这里的模拟实现先是创建了一个 char* ret用来保存原来目标字符串的起始地址(因为后面dest会改变),这样为后来的返回值做准备

这里直接简写成了用一个循环判断即可,当src为'\0'的时候赋值给dest自然就会停下循环

strcat的使用和模拟实现

strcat的使用

该函数的作用是可以把一个字符串连接到另一个字符串上面,也是以'\0'为标志结束

注意:目标空间必需要足够大且可修改,不然会越界

strcat的模拟实现

#include <stdio.h>char* my_strcat(char* dest, const char* src)
{char* ret = dest;while (*dest)dest++;while (*dest++ = *src++);return ret;
}int main()
{char arr1[20] = "Hello ";char arr2[] = "World";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

这里的模拟实现先是创建了一个 char* ret用来保存原来目标字符串的起始地址(因为后面dest会改变),这样为后来的返回值做准备

第一个循环的作用是找到dest的第一个'\0'

第二个循环即类似strcpy拷贝到末尾即可

最后返回起始dest的地址

strcmp的使用和模拟实现

strcmp的使用

该函数的作用是对两个字符串比较大小,从起始地址开始直到碰到'\0'结束一 一比较

如果直到结束两个字符都是相同的那么就说明字符串相等,则返回0

如果str1大于str2,返回大于0的数字,str1小于str2,返回小于0的数字(具体什么数字不做要求)

strcmp的模拟实现

#include <stdio.h>int my_strcmp(const char* str1, const char* str2)
{while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}int main()
{char arr1[10] = "abcde";char arr2[10] = "abq";int ret = my_strcmp(arr1, arr2);printf("%d", ret);return 0;
}

一个循环遍历两个字符串

如果走到'\0'则结束返回0

如果循环条件结束,则判断谁的ASCLL码值大,返回1或-1

strstr的使用和模拟实现

strstr的使用

该函数会在str1中寻找字符串str2

如果找不到则返回null

如果找到了会返回找到位置的起始地址

strstr的模拟实现

#include <stdio.h>char* my_strstr(const char* str1, const char* str2)
{char* ptr1 = str1;char* ptr2 = str2;char* cur = str1;while (*cur != '\0'){ptr1 = cur;ptr2 = str2;while (*ptr1 == *ptr2 && cur != '\0' && ptr2 != '\0'){ptr1++;ptr2++;}if (*ptr2 == '\0')return cur;cur++;}return NULL;
}int main()
{char arr1[20] = "hello@world.c";char arr2[20] = "llo";char* ret = my_strstr(arr1, arr2);printf("%s", ret);return 0;
}

这里需要定义几个char* 类型的变量来代替str1和str2移动

因为我们如果只有str1和str2就算能够找到str1中的str2也无法后退返回原来的地址了

 例如:

 

如果我们从str1中找str2的时候,发现了第一个l,那么往后走发现第二个不是o的时候,我们如何返回呢?

str2判断完str1的ll不是lo的时候str2又怎么返回到str2的起始地址l中呢?

所以这就是需要定义多个char* 类型的变量来走的原因

第一个循环的cur是用来遍历的

第二个循环是用来判断字符串是否相同的 

最后都返回找到的起始位置或者NULL即可

strncpy的使用和模拟实现

strncpy和strcpy的区别就差了一个n

这类型的函数有很多,都是加了一个n

这类函数会更加安全,因为strcpy拷贝的时候如果没有控制好数组的大小就会有越界的风险

所以strncpy的安全性会更高 

strncpy的使用

strncpy可以自己选择需要拷贝多少个数据,我们只需要传参的时候多传一个num即可 

这个num的单位是字节

strncpy的模拟实现

#include <stdio.h>char* my_strncpy(char* dest, const char* str, size_t num)
{char* ret = dest;int i = 0;for (int i = 0; i < num; i++){*(dest + i) = *(str + i);}return ret;
}int main()
{char arr1[] = "abcdefg";char arr2[20] = { 0 };my_strncpy(arr2, arr1 + 1, 5);printf("%s", arr2);return 0;
}

这里的实现和strcpy差不多

只不过用了个for循环来控制需要拷贝几个字符串即可

strncat的使用和模拟实现

strncat的使用

strcat是连接字符串

那么strncat就是可以决定需要连接几个字符串

strncat的模拟实现

#include <stdio.h>char* my_strncat(char* dest, char* str, size_t num)
{char* ret = dest;while (*dest != '\0'){dest++;}for (int i = 0; i < num; i++){*(dest++) = *(str++);}return ret;
}int main()
{char arr1[20] = "hello";char arr2[20] = " world";my_strncat(arr1, arr2 + 1, 3);printf("%s", arr1);return 0;
}

具体实现也和strcat差不多

for循环控制连接字符串个数

strncmp的使用和模拟实现

strncmp的使用

strcmp是比较两个字符串

strncmp是比较指定个数的两个字符串

其他的基本一致

strncmp的模拟实现

#include <stdio.h>int my_strncmp(const char* str1, const char* str2, size_t num)
{for (int i = 0; i < num; i++){if (*str1 > *str2)return 1;if (*str1 < *str2)return -1;str1++;str2++;}return 0;
}int main()
{char arr1[10] = "abcde";char arr2[10] = "abq";int ret = my_strncmp(arr1, arr2, 3);printf("%d", ret);return 0;
}

用for循环控制比较的字符个数

其他的与strcmp差不多一致

感谢观看


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

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

相关文章

unity3d Animal Controller的Animal组件中General基础部分理解

控制器介绍 动物脚本负责控制动物的所有运动逻辑.它管理所有的动画师和刚体参数,以及所有的状态和模式,动物可以做。 动物控制器 是一个动画框架控制器,根动或到位,为任何生物或人形。它利用刚体与物理世界的互动和动画师的玩动画。 States States 是不互相重叠的动画。例如…

PMP的学习方法

PMBOK编撰了管理项目需要的49个过程&#xff08;输入、工具技术、输出&#xff09;。工具技术文件&#xff0c;林林总总百余个。第一部分&#xff0c;按照十大知识领域顺序从前到后编排&#xff1b;第二部分&#xff0c;按照五大过程组顺序重新编排了一遍。 一&#xff0c;PMB…

20240313寻找集成联调交付的具体方式

集成联调交付&#xff08;Integrated Joint Debugging and Delivery&#xff09;是软件开发过程中的一个阶段&#xff0c;主要涉及将不同的软件模块或组件整合在一起&#xff0c;并进行联合调试和测试&#xff0c;以确保它们能够作为一个整体正常工作。这个过程通常发生在开发周…

手搭手RocketMQ重试机制

环境介绍 技术栈 springbootmybatis-plusmysqlrocketmq 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3.1.7 dynamic-datasource 3.6.1 mybatis-plus 3.5.3.2 rocketmq 4.9.4 加入依赖 <dependencies><dependency><…

【Poi-tl Documentation】自定义占位符来设置图片大小

前置说明&#xff1a; <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version> </dependency>模板文件&#xff1a; image_test.docx package run.siyuan.poi.tl.policy;imp…

调皮的String及多种玩法(下部)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…

某赛通电子文档安全管理系统 DecryptApplication 任意文件读取漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

国创证券策略:股指预计维持震荡格局 关注汽车、通信设备等板块

国创证券指出&#xff0c;近期两市指数持续反弹创新高&#xff0c;但沪指现已率先出现滞涨状况&#xff0c;一起均已进入阻力重压区。不过当时技术形状上坚持较好&#xff0c;可持续做多&#xff0c;一旦跌破重要支撑如沪指的3030点&#xff0c;则需降仓防卫&#xff0c;防止指…

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 1、线条折线曲面

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 代码: import pandas as pd import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib.colors import ListedColor…

释放人工智能的力量:GPU服务器托管和高电机柜托管的关键作用

随着人工智能技术的不断发展&#xff0c;GPU服务器托管和高电机柜托管也变得愈发重要。这些技术在人工智能领域发挥着关键作用&#xff0c;为AI算法的训练和推理提供了强大的计算支持。 GPU服务器托管是指将GPU服务器放置在专门的数据中心中&#xff0c;通过云服务提供商提供的…

网络学习:BGP路径属性分类

目录 前言&#xff1a; 路径属性分类 公认必遵 公认任意 可选过渡 可选非过渡 前言&#xff1a; 在默认情况下&#xff0c;到达同一目的地&#xff0c;BGP只走单条路径&#xff0c;并不会在多条路径之间执行负载均衡。对于IGP路由协议&#xff0c;当有多条路径可以到达同…

RPC通信原理(一)

RPC通信原理 RPC的概念 如果现在我有一个电商项目&#xff0c;用户要查询订单&#xff0c;自然而然是通过Service接口来调用订单的实现类。 我们把用户模块和订单模块都放在一起&#xff0c;打包成一个war包&#xff0c;然后再tomcat上运行&#xff0c;tomcat占有一个进程&am…

Netty线程模型详解

文章目录 概述单Reactor单线程模型单Reactor多线程模型主从Reactor多线程模型 概述 Netty的线程模型采用了Reactor模式&#xff0c;即一个或多个EventLoop轮询各自的任务队列&#xff0c;当发现有任务时&#xff0c;就处理它们。Netty支持单线程模型、多线程模型和混合线程模型…

chown: changing ownership of ‘.‘: Permission denied 的一种解法

前言 最近在新电脑用 colima docker 启动服务遇到了这样的报错 chown: changing ownership of .: Permission denied在网上搜索了很久&#xff0c;不管是google还是stack overflow都没有突破口&#xff0c;只要绑定了 volumes 就会报错&#xff0c;按照网上说的方法&#xff…

【Unity】读取Json的三种方法(JsonUtility,LitJson,Newtonsoft)

介绍 在Unity开发过程中&#xff0c;Json是比较常用的一种数据存储文本&#xff0c;尤其是在和第三方交互中&#xff0c;基本都是json格式。 先给出一个Json示例&#xff0c;我们来看看是如何解析的。 {"Player": [{"id": 1001,"name": "…

【JVM】GCRoot

GC root原理 通过对枚举GCroot对象做引用可达性分析&#xff0c;即从GC root对象开始&#xff0c;向下搜索&#xff0c;形成的路径称之为 引用链。如果一个对象到GC roots对象没有任何引用&#xff0c;没有形成引用链&#xff0c;那么该对象等待GC回收。 可以作为GC Roots的对…

云原生基础知识:容器技术的历史

容器化的定义&#xff1a; 容器化是一种轻量级的虚拟化技术&#xff0c;将应用程序及其所有依赖项&#xff08;包括运行时、系统工具、系统库等&#xff09;打包到一个称为容器的单独单元中。容器提供了一种隔离的执行环境&#xff0c;使得应用程序可以在不同的环境中运行&…

居民健康监测小程序|基于微信小程序的居民健康监测小程序设计与实现(源码+数据库+文档)

居民健康监测小程序目录 目录 基于微信小程序的居民健康监测小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2、健康科普管理 5.3公告类型管理 3、论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

LeetCode每日一题——移除元素

移除元素OJ链接&#xff1a;27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 题目给定要求只能使用O(1)的额外空间并且原地修改输入数组&#xff0c;然后返回移除后的数组行长度。那 么我们就可以确我没有办法建立临时的数组存放我…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…