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.hqwc.cn/news/543220.html

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

相关文章

深入浅出落地应用分析:AI数字人「微软小冰」

hi,各位,今天要聊的是AI小冰,机缘巧合,投递了这家公司的产品,正好最近在看数字人相关的,就详细剖析下这款产品! 前言 小冰,全称为北京红棉小冰科技有限公司,前身为微软(亚洲)互联网工程院人工智能小冰团队,是微软全球最大的人工智能独立产品研发团队。作为微软全…

GaN HEMTs在电力电子应用中的交叉耦合与基板电容分析与建模

来源&#xff1a;Analysis and Modeling of Cross-Coupling and Substrate Capacitances in GaN HEMTs for Power-Electronic Applications&#xff08; TED 17年&#xff09; 摘要 本文提出了一种考虑了基板电容与场板之间交叉耦合效应的场板AlGaN/GaN高电子迁移率晶体管(HE…

机器学习-04-分类算法-03KNN算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与knn算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化…

在Vue中使用wangeditor创建富文本编辑器的完整指南

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

计算机考研|王道四本书够吗?

如果你是跨考生&#xff0c;王道的四本书只能覆盖你需要的80% 如果你是计算机专业的考生&#xff0c;王道四本书可以覆盖你需要的90% 我已经说的很明显了&#xff0c;王道的内容覆盖不了408考研的全部大纲&#xff0c;有的知识点虽然在王道书上提到了&#xff0c;但是因为不是…

京东云,华为,格行随身wifi大对比,2024最值得购买的随身WiFi

最近关于随身wifi的话题热度不降&#xff0c;京东自主品牌京东云随身wifi一经推出&#xff0c;很多网友纷纷想体验一下&#xff0c;更有网友直呼碾压老大哥华为随身wifi&#xff0c;一起来看一下京东云随身wifi到底怎么样&#xff1f; 京东云随身wifi是京东自主品牌&#xff0…

python3GUI--qt仿暴风影音By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;环境1.开发环境2.打包环境3.运行环境 三&#xff0e;软件截图1.启动页2.视频播放3.音频播放4.其他1.托盘2.对话框 四&#xff0e;功能总览五&#xff0e;代码展示&心得1.UI设计2.如何防止卡顿3.如何自定义组件 五&#xff0e;思考…

testng测试类

第一步&#xff1a;在测试类中写业务逻辑测试代码在测试类中插入testng相关注解 数据驱动给test标记的方法提供数据 看数据驱动源码 在TestNG中&#xff0c;你可以使用DataProvider注解来标记一个方法&#xff0c;该方法将提供数据给测试方法。数据提供者的名称默认为方法名。…

淘宝扭蛋机小程序系统:电商娱乐新纪元,开启无限惊喜之旅

在移动互联网蓬勃发展的今天&#xff0c;小程序以其轻便、快捷的特性&#xff0c;成为了众多用户的新宠。淘宝作为国内电商领域的领军者&#xff0c;始终站在创新的前沿&#xff0c;不断探索和尝试新的商业模式。在这样的背景下&#xff0c;淘宝扭蛋机小程序系统应运而生&#…

JAVA-反射

JAVA-反射(reflection) 01. 一个需求引出反射 1. 问题 根据配置文件 re.properties 指定信息&#xff0c;创建Cat对象并调用方法hi re.properties: calssfullpathcom.yzjedu.Cat methodhi使用现有的技术&#xff0c;可以做到吗&#xff1f; cat类&#xff1a; package com…

网站安全监测:守护网络空间的坚实防线

随着互联网技术的飞速发展和广泛应用&#xff0c;网站已成为企业、机构和个人展示形象、提供服务、传递信息的重要平台。然而&#xff0c;与此同时&#xff0c;网站也面临着日益严重的安全威胁。黑客攻击、数据泄露、恶意软件等安全问题频发&#xff0c;给网站运营者带来了巨大…

GUROBI建模之非线性约束的处理

官方文档 目录 官方文档&#xff1a;GRBModel.AddGenConstrXxx() - Gurobi Optimization 数学规划的约束类型 基本约束(fundamental constraints)&#xff1a; 通用约束(general constraints): 1. GUROBI求解器有针对这类约束的函数&#xff0c;直接调用这类函数即可 2.…