(c语言进阶)字符串函数、字符分类函数和字符转换函数

一.求字符串长度

1.strlen()

(1)基本概念

头文件:<string.h>

(2)易错点:strlen()的返回值为无符号整形

#include<stdio.h>
#include<string.h>
int main() 
{const char* str1 = "abcdef";const char* str2 = "bbb";printf("%u\n", strlen(str2) - strlen(str1));printf("%d\n", strlen(str2) - strlen(str1));return 0;
}

 

两个strlen函数的返回值相减,得到的结果为无符号整数的形式

#include<stdio.h>
#include<string.h>
int main() 
{const char* str1 = "abcdef";const char* str2 = "bbb";if (strlen(str2) - strlen(str1) > 0){printf(">\n");}else{printf("<\n");}return 0;
}

 (3)模拟实现

#include<stdio.h>
#include<string.h>
size_t my_strlen(const char* str1)
{size_t count=0;while (*str1++){count++;}return count;
}
int main() 
{const char* str1 = "abcdef";size_t len=my_strlen(str1);printf("%u",len);return 0;
}

二.长度不受限制的字符串函数

1.strcpy()——将源字符串复制给目标字符串

(1)基本概念

头文件:<string.h>

#include<stdio.h>
#include<string.h>
int main()
{char name[20] = {0};//目标字符串的空间要足够大,否则会出现数组越界现象char arr[20] = "hhhhhhhhhh";strcpy(name,arr);//arr为字符串首元素的地址//strcpy(目标字符串首元素地址,字符串常量首元素地址)//'\0'也会被复制到目标字符串printf("%s\n",name);strcpy(name,"ycy");printf("%s",name);return 0;
}

(2)易错点:目标空间不够大时,字符串的复制还是会进行,代价是通过数组越界来实现的

(3)模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* name,char* arr)
{assert(name&&arr);char* p = name;while (*name++=*arr++) //赋值语句的返回值为左操作数的值,当*arr将'\0'赋值给*name时结束循环{}return p;
}
int main()
{char name[20] = {0};char arr[20] = "hhhhhhhhhh";my_strcpy(name,arr);printf("%s",name);return 0;
}

 

2.strcat()——字符串追加

 (1)基本概念

头文件<string.h>

 (2)模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* arr1,char* arr2)
{char* p = arr1;//将地址移动至\0处while (*arr1){arr1++;}//从\0处开始拷贝arr2//h e l l o \0——arr1//  w o r l d \0——arr2//h e l l o  w o r l d \0 ——追加后的arr1while (*arr1++ = *arr2++){}return p;
}
int main()
{char arr1[20] = "hello";char arr2[20] = " world";my_strcat(arr1,arr2);printf("%s",arr1);return 0;
}

3.strcmp()——字符串比较

(1)基本概念

头文件<string.h> 

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello";char arr2[20] = "world";int p=strcmp(arr1,arr2);//strcmp函数会将两个字符串的每个字符依次比较//若出现不相等则停止比较//前一个操作符的元素大于后一个操作符的元素,则会输出一个大于零的整数//前一个操作符的元素小于后一个操作符的元素,则会输出一个小于零的整数、//等于则输出0if (p > 0){printf("arr1>arr2\n");}else if (p == 0){printf("arr1==arr2\n");}else{printf("arr1<arr2\n");}return 0;
}

 (2)模拟实现

include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(char* arr1,char* arr2)
{assert(arr1&&arr2);while (*arr1==*arr2) //相同的情况下,判断下一位是否也相同,不相同则退出循环{if (*arr1=='\0'||*arr2=='\0')  //若有其中一个字符串到达末尾,则退出循环{break;}arr1++;arr2++;}return *arr1 - *arr2;  //不相同则相减返回差值
}
int main()
{char arr1[20] = "hello";char arr2[20] = "hello";int p=my_strcmp(arr1,arr2);if (p > 0){printf("arr1>arr2\n");}else if (p == 0){printf("arr1==arr2\n");}else{printf("arr1<arr2\n");}return 0;
}

三.长度受限制的字符串函数介绍

1.strncpy() ——可控制,复制字符串元素

 (1)基本概念

头文件<string.h> 

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "abcdef";char arr2[] = "bit";strncpy(arr1,arr2,3);printf("%s\n",arr1);return 0;
}

 (2)易错点:当要复制的元素个数大于原字符串时,多出来的位置会用\0代替

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "abcdef";char arr2[] = "bit";strncpy(arr1,arr2,5);printf("%s\n",arr1);return 0;
}

 (3)模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncpy(char* arr1,char* arr2,size_t x)
{assert(arr1&&arr2);	char *p= arr1;int i;int len = strlen(arr2);for (i = 0; i < x; i++){if (i>len){*arr1++ = '\0';}else{*arr1++ = *arr2++;}}return p;
}
int main()
{char arr1[20] = "abcdef";char arr2[] = "bit";my_strncpy(arr1,arr2,5);printf("%s\n",arr1);return 0;
}

2.strncat()——可控制,链接字符串元素

(1)基本概念 

头文件<string.h> 

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello";char arr2[] = "bit";strncat(arr1,arr2,3);printf("%s\n",arr1);return 0;
}

(2)易错点:需要链接的元素个数小于原字符串时,会在链接相应数量元素的同时多链接一个'\0' .元素个数大于原字符串时,不会用'\0'填补

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello";char arr2[] = "bit";strncat(arr1,arr2,5);printf("%s\n",arr1);return 0;
}
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello";char arr2[] = "bit";strncat(arr1,arr2,1);printf("%s\n",arr1);return 0;
}

(3)模拟实现 

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strncat(char* arr1,char*arr2,size_t x)
{assert(arr1&&arr2);int len = strlen(arr2);char* p = arr1;while (*arr1 != '\0'){arr1++;}if (x >= len){while (*arr2){*arr1++ = *arr2++;}}else{for (int i = 0; i < x; i++){*arr1++ = *arr2++;}*arr1 = '\0';}return p;
}
int main()
{char arr1[20] = "hello";char arr2[] = "bit";my_strncat(arr1,arr2,5);printf("%s\n",arr1);return 0;
}

3.strncmp()——可控制,比较字符串元素 

 (1)基本概念

头文件<string.h> 

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello";char arr2[] = "bit";int ret=strncmp(arr1,arr2,3);if (ret > 0){printf("arr1>arr2");}else if (ret == 0){printf("arr1==arr2");}else{printf("arr1<arr2");}return 0;
}

四.字符串查找

1.strstr()——在一个字符串中查找另一个字符串是否存在

 (1)基本概念

头文件<string.h> 

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char arr1[20] = "hello bit world";char arr2[] = "bit";char*ret = strstr(arr1,arr2);//ret为寻找到字串位置的首地址if (ret == NULL){printf("所寻找的子串不存在\n");}else{printf("%s",ret);//从地址处往后输出}return 0;
}

 (2)模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1&&str2);  //判断参数不为空const char* s1 = str1;const char* s2 = str2;const char* p = str1;while (*p) //被查找的字符串不为空{s1 = p;s2 = str2;  //始终指向查找字符串的首元素地址while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)  //都不为空且相等时进入循环{s1++;s2++;}if (*s2 == '\0') //如果退出循环时查找字符串到最后都是相等的,则说明查找成功{return p; //返回查找到的首地址}p++; //若查找途中存在不相同的,则被查找字符串指针向后一位}return NULL;
}
int main()
{char arr1[20] = "hello bit world";char arr2[] = "bit";char* ret = my_strstr(arr1, arr2);//ret为寻找到字串位置的首地址if (ret == NULL){printf("所寻找的子串不存在\n");}else{printf("%s", ret);//从地址处往后输出}return 0;
}

 

2.strtok()——切割字符串

 (1)基本概念

头文件<string.h> 

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{const char* sep = '@';  //分隔符char email[] = "zhangpengwei@bietejieyeke.com";  //被分割的字符串strtok(email,sep); //因为strtok函数会将遇到的第一个分隔符改为'\0',
//并返回分隔符的指针,将改变原有字符串
//__________________________________________________________________________________//若不想原有字符串被改变则采用如下操作char cp[] = {0};strcpy(cp,email);strtok(cp,sep);return 0;
}

 (2)简单应用

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{const char* sep = "@.";  //分隔符char email[] = "zhangpengwei@bietejieyeke.com";  //被分割的字符串char cp[30] = {0};strcpy(cp,email);  //strtok函数有记忆功能,执行完后会保存上一个分隔符的地址,下一次调用时从该地址往后查找char* ret=strtok(cp,sep);printf("%s\n",ret);ret = strtok(NULL,sep);  //所以除第一次调用,多次调用时不需要传入参数,所以传入NULLprintf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);return 0;
}

 (3)优化

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{const char* sep = "@.";  //分隔符char email[] = "zhangpengwei@bietejieyeke.com";  //被分割的字符串char cp[30] = {0};strcpy(cp,email);  char* ret = NULL;for (ret = strtok(cp, sep); ret != NULL; ret=strtok(NULL, sep)){printf("%s\n",ret);}return 0;
}

五.错误信息报告

1.strerror()——返回错误码所对应的错误信息

 (1)基本概念

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{//c语言的库函数在执行失败的时候,都会设置相应的错误码//0 1 2 3 4 5 6 7 8 ......//strerror()可以返回错误码所对应的错误信息printf("%s\n", strerror(1));printf("%s\n", strerror(2));printf("%s\n", strerror(3));printf("%s\n", strerror(4));printf("%s\n", strerror(5));printf("%s\n", strerror(6));printf("%s\n", strerror(7));printf("%s\n", strerror(8));return 0;
}

 (2)简单应用

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<errno.h>
int main()
{//打开文件的函数为fopen()//"r"表示以读的形式打开//返回的是FILE型的指针,如果打开失败会返回空指针(NULL)FILE* pf = fopen("text.txt","r");//若打开的文件在程序路径下,可以使用相对路径(文件名)fopen("C:\\Users\\admin\\Desktop\\text2.text","r");//在其他位置要使用绝对路径,单个'\'会被识别为转义字符,所以要再加一个'\'//打开文件失败后,fopen函数会将错误码存储在errno中//errno—C语言设置的一个全局的错误码存储变量//只要发生错误,都会把错误码存在errno中—始终记录最新的错误码//调用errno需要应用头文件<errno.h>if (pf == NULL){printf("%s", strerror(errno));}return 0;
}

六.字符分类函数 ——头文件<ctype.h>

重点:应用

举例:isspace()——判断空白字符

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{printf("%d\n", isspace('x'));printf("%d\n", isspace(' '));return 0;
}

1、iscntrl()——判断是否是控制字符(任何控制字符)

功能 

判断是否是控制字符(任何控制字符)

返回值

若返回值为非0数字,则为控制字符,若返回0,则不是控制字符。

2、isspace()——判断是否是空白字符

功能:

判断是否是空白字符(空格、换页/f、换行\n,回车\r,制表符\t或者垂直制表符\v)

返回值:

若返回值为非0数字,则为空白字符,若返回0,则不是空白字符。

3、isdigit()——判断是否是十进制数字字符

功能:

判断是否是十进制数字字符(0-9)

返回值:

若返回值为非0数字,则为十进制数字字符,若返回0,则不是十进制数字字符。


4、isxdigit()——判断是否是十六进制数字字符

功能:

判断是否是十六进制数字字符(包括所有十进制数字,小写字母a-f,大写字母A-F)

返回值:

若返回值为非0数字,则为十六进制字符,若返回0,则不是控制字符。

5、islower()——判断是否是小写字母

功能:

判断是否是小写字母(a-z)

返回值:

若返回值为非0数字,则为小写字母字符,若返回0,则不是小写字母字符


6、isupper()——判断是否是大写字母

功能:

判断是否是大写字母(A-Z)

返回值:

若返回值为非0数字,则为大写字母字符,若返回0,则不是大写字母字符。


7、isalpha()——判断是否是字母字符

功能:

判断是否是字母字符(a-z或A-Z)

返回值:

返回值为非0数字则为控制字符,返回0则不是控制字符。


8、isalnum()——判断是否是字母字符或者数字字符

功能:

判断是否是字母字符或者数字字符(a-z、A-Z、0-9)

返回值:

若返回值为非0数字,则为字母字符或数字字符,若返回0,则不是字母字符或数字字符。


9、ispunct()——判断是否是标点符号字符

功能:

判断是否是标点符号字符(任何不属于数字或字母的图形字符)

返回值:

若返回值为非0数字,则为标点符号,若返回0,则不是标点符号。


10、isgraph()——判断是否是图形字符

功能:

判断是否是图形字符(任何图形字符)

返回值:

若返回值为非0数字,则为图形字符,若返回0,则不是图形字符。


11、isprint()——判断是否是可打印字符

功能:

判断是否是可打印字符(包括图形字符和空白字符)

返回值:

若返回值为非0数字,则为可打印字符,若返回0,则不是可打印字符。

 七.字符转换函数

1.tolower(int c) ——字符转小写

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{printf("%c\n",tolower('H'));return 0;

 

2.toupper(int c) ——字符转大写

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{printf("%c\n",toupper('h'));return 0;

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

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

相关文章

审核 Microsoft SQL Server 日志

手动审核数据库活动是一项艰巨的任务&#xff0c;有效完成审计的最佳方法是使用简化和自动化数据库监控的综合解决方案&#xff0c;该解决方案还应使数据库管理员能够监控、跟踪和即时识别任何操作问题的根本原因&#xff0c;并实时检测对机密数据的未经授权的访问。 什么是 S…

前端面试 面试多起来了

就在昨天 10.17 号,同时收到了三个同学面试的消息。他们的基本情况都是双非院校本科、没有实习经历、不会消息中间件和 Spring Cloud 微服务,做的都是单体项目。但他们投递简历还算积极,从今年 9 月初就开始投递简历了,到现在也有一个多月了。 来看看,这些消息。 为…

中文编程工具免费版下载,中文开发语言工具免费版下载

中文编程工具免费版下载&#xff0c;中文开发语言工具免费版下载 中文编程工具开发的实际部分案例如下图 编程系统化课程总目录及明细&#xff0c;点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.2014.3001.5502

RabbitMQ消息中间件

一、初始MQ 首先了解一下微服务间通讯有同步和异步两种方式&#xff1a;- 同步通讯&#xff1a;是指两个或多个系统在进行信息交换时&#xff0c;必须在同一时刻进行操作 - 异步通讯&#xff1a;是指两个或多个系统之间的通讯方式&#xff0c;其中发送方和接收方不是在同一时刻…

星环科技分布式向量数据库Transwarp Hippo正式发布,拓展大语言模型时间和空间维度

随着企业、机构中非结构化数据应用的日益增多以及AI的爆发式增长所带来的大量生成式数据&#xff0c;所涉及的数据呈现了体量大、格式和存储方式多样、处理速度要求高、潜在价值大等特点。但传统数据平台对这些数据的处理能力较为有限&#xff0c;如使用文件系统、多类不同数据…

Vue显示FFmpeg推的流

零、环境安装 小弟的另一篇文章&#xff1a; FFmpeg和rtsp服务器搭建视频直播流服务-CSDN博客 一、FFmpeg推流 1、拉取rtsp摄像头流 sudo ffmpeg -f v4l2 -input_format mjpeg -i /dev/video0 -c:v copy -f rtsp rtsp://10.168.3.196:8554/mystream2、推视频的rtmp流 sudo ffm…

python数据可视化

内容主要介绍了python模块matplotlib即seaborn数据可视化 matplotlib模块通过import matplotlib.pyplot as plt生成图形&#xff0c;如生成图形没展示&#xff0c;可调用plt.show()方法展示图形&#xff1b; 对于颜色属性设置&#xff0c;既可以使用十六进制颜色表达(#7777aa…

图像特征Vol.1:计算机视觉特征度量|第一弹:【纹理区域特征】

目录 一、前言二、纹理区域度量2.1&#xff1a;边缘特征度量2.2&#xff1a;互相关和自相关特征2.3&#xff1a;频谱方法—傅里叶谱2.4&#xff1a;灰度共生矩阵(GLCM)2.5&#xff1a;Laws纹理特征2.6&#xff1a;局部二值模式&#xff08;LBP&#xff09; 一、前言 &#x1f…

【网络安全 --- 任意文件上传漏洞靶场闯关 6-15关】任意文件上传漏洞靶场闯关,让你更深入了解文件上传漏洞以及绕过方式方法,思路技巧

一&#xff0c;工具资源下载 百度网盘资源下载链接地址&#xff1a; 百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan…

Generative AI 新世界 | Falcon 40B 开源大模型的部署方式分析

在上期文章&#xff0c;我们探讨了如何在自定义数据集上来微调&#xff08;fine-tuned&#xff09;模型。本期文章&#xff0c;我们将重新回到文本生成的大模型部署场景&#xff0c;探讨如何在 Amazon SageMaker 上部署具有 400 亿参数的 Falcon 40B 开源大模型。 亚马逊云科技…

干货!数字IC后端入门学习笔记

很多同学想要了解IC后端&#xff0c;今天大家分享了数字IC后端的学习入门笔记&#xff0c;供大家学习参考。 很多人对于后端设计的概念比较模糊&#xff0c;需要做什么也都不甚清楚。 有的同学认为就是跑跑 flow、掌握各类工具。 事实上&#xff0c;后端设计的工作远不止于此。…

【C++笔记】C++多态

【C笔记】C多态 一、多态的概念及实现1.1、什么是多态1.2、实现多态的条件1.3、实现继承与接口继承1.4、多态中的析构函数1.5、抽象类 二、多态的实现原理 一、多态的概念及实现 1.1、什么是多态 多态的概念&#xff1a; 在编程语言和类型论中&#xff0c;多态&#xff08;英…

DNS 域名解析系统

文章目录 前言什么是 DNS 域名解析系统为什么需要 DNS 域名解析DNS 是如何发展的hosts 文件维护域名和IP的映射关系DNS 系统&#xff08;服务器&#xff09;DNS 镜像系统 前言 前面为大家分享了关于计算机网络中应用层——自定义协议、传输层——UDP、TCP 协议、网络层——IP协…

Java修仙传之Flink篇

大道三千:最近我修Flink 目前个人理解&#xff1a; 处理有界&#xff0c;无界流的工具 FLINK&#xff1a; FLINK定义&#xff1a; Flink特点 Flink分层API 流的定义 有界数据流&#xff08;批处理&#xff09;&#xff1a; 有界流&#xff1a;数据结束了&#xff0c;程序也…

大数据之LibrA数据库系统告警处理(ALM-12005 OKerberos资源异常)

告警解释 告警模块对Manager中的Kerberos资源的状态进行监控&#xff0c;当Kerberos资源异常时&#xff0c;系统产生此告警。 当Kerberos资源恢复时&#xff0c;且告警处理完成时&#xff0c;告警恢复。 告警属性 告警参数 对系统的影响 Manager中的Kerberos资源异常&#…

ceph高可用、手动安装

操作系统&#xff1a;centos8 三台服务器&#xff1a; 192.168.6.22&#xff1a;mon,mgr,mds,osd 192.168.6.23&#xff1a;mon,mgr,mds,osd 192.168.6.24&#xff1a;mon,mgr,mds,osd 正式环境osd和mon不应该在一个节点&#xff0c;建议osd单独服务器安装。 ceph版本&am…

element表格自定义筛选

文章目录 前言一、简介二、效果展示三、源码总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; …待续 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、简介 修改el-table的筛选…待续 二、效果展示 三、源码 使用方法…

sentinel规则持久化-规则同步nacos-最标准配置

官方参考文档&#xff1a; 动态规则扩展 alibaba/Sentinel Wiki GitHub 需要修改的代码如下&#xff1a; 为了便于后续版本集成nacos&#xff0c;简单讲一下集成思路 1.更改pom 修改sentinel-datasource-nacos的范围 将 <dependency><groupId>com.alibaba.c…

[SUCTF 2019]EasySQL 1

题目环境&#xff1a; 把你的旗子给我&#xff0c;我会告诉你旗子是不是对的。 判断注入类型1回显结果 不是字符型SQL注入 1回显结果 数字型SQL注入 查所有数据库,采用堆叠注入1;show databases;查看所有数据表1;show tables;尝试爆Flag数据表的字段1;show columns from Flag; …

LeetCode | 27. 移除元素

LeetCode | 27. 移除元素 OJ链接 这道题有一个方法是要删除的数据直接后一个数据挪动到前一个数据&#xff0c;这个方法好不好&#xff1f;最坏的情况下时间复杂度是O(N^2) 还有一个方法 定义一个src定义一个dst&#xff0c;原地直接进行赋值&#xff0c;不进行挪动&#xf…