C语言--字符函数与字符串函数
大家好,我是残念,希望在你看完之后,能对你有所帮助,有什么不足请指正!共同学习交流
本文由:残念ing 原创CSDN首发,如需要转载请通知
个人主页:残念ing-CSDN博客,欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:残念ing 的C语言系列专栏——CSDN博客
目录
前言:
1.字符分类函数
2.字符转换函数
3.strlen 函数
3.1 正确使用strlen函数
3.2 模拟实现strlen函数
4. strcpy 函数
4.1 strcpy的使用
4.2 模拟实现strcpy
5. strcat 函数
5.1 strcat的使用
5.2 模拟实现strcat
6. strcmp 函数
6.1 strcmp的使用
6.2 模拟实现strcmp
7. strncpy函数
7.1 strncpy 的使用
8.strncat 函数
8.1 strncat 的使用
9. strncmp 函数
9.1 strncmp 的使用
10. strstr 函数
10.1 strstr 的使用
10.2 模拟实现strstr
11. strtok 函数
11.1 strtok 的使用
12. strerror 函数
12.1 strerror 的使用
前言:
我们在编程过程中,我们阶乘要处理到一下字符和字符串,为了方便操作字符和字符串,C语言为我们太贵了一系列的库函数,现在我们就来学一下这些函数吧。
1.字符分类函数
在C语言中专门有一些函数是做字符分类的,就是判断一个字符属于什么类型的字符。
注:使用这些函数必须包含头文件 <ctype.h>
函数 | 如果参数符合下列条件返回真 |
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)
//islower是判断参数c是否是小写字母,如果是返回非0的整数,如果不是,则返回0;
练习:将字符串中的小写字母转换为大小字母,其他字符不变
#include <stdio.h>
#include <ctype.h>
int main()
{int i = 0;char str[] = "Test String\n";char c;while (str[i]){c = str[i];if (islower(c))c -= 32;//小写字母转换成大写字母-32putchar(c);//打印ci++;}return 0;
}
2.字符转换函数
C语言中提供了2个字符转换函数
int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
我们知道了这两个函数,我们就可以把上面的类型写为
#include <stdio.h>
#include <ctype.h>
int main()
{int i = 0;char str[] = "Test String\n";char c;while (str[i]){c = str[i];if (islower(c))c = toupper(c);//将小写字母转换成大写字母putchar(c);i++;}return 0;
}
3.strlen 函数
size_t strlen ( const char * str );
注意:
1. 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包 含 '\0' )。
2. 参数指向的字符串必须要以 '\0' 结束。
3. 注意函数的返回值为size_t,是⽆符号的( 易错 )
4. strlen的使⽤需要包含头⽂件(<string.h>)
3.1 正确使用strlen函数
#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "abcdef";const char* str2 = "bbbbb";if (strlen(str2) - strlen(str1) > 0){printf("str2>str1\n");}else{printf("srt1>str2\n");}return 0;
}
3.2 模拟实现strlen函数
//方法1:
//计数器⽅式
int my_strlen(const char* str)
{int count = 0;assert(str);while (*str){count++;str++;}return count;
}
//方法2
//不能创建临时变量计数器(递归)
int my_strlen(const char* str)
{assert(str);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
//方法3
//指针-指针的⽅式
int my_strlen(char* str)
{assert(str);char* p = str;while (*p != '\0')p++;return p - str;
}
4. strcpy 函数
char* strcpy(char * destination, const char * source );
功能: 将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)
注:
1. 源字符串必须以'\0'结束。
2. 会将源字符串中的'\0'拷贝到目标空间
3. 目标空间必须足够大,以确保能存放源字符串。
4. 目标空间必须可以修改
4.1 strcpy的使用
int main()
{char arr1[] = "abcdef";char arr2[20] = "";char* ret = strcpy(arr2, arr1);for (int i = 0; i < 20; i++){printf("%c", arr2[i]);}return 0;
}
4.2 模拟实现strcpy
char* my_strcpy(char* p1, const char* p2)
{while (*p2 != '\0'){*p1 = *p2;p1++;p2++;}return p1;
}
int main()
{char arr1[] = "abcdef";char arr2[20] = "";char* ret = my_strcpy(arr2, arr1);for (int i = 0; i < 20; i++){printf("%c", arr2[i]);}return 0;
}
5. strcat 函数
char* strcat(char * destination, const char * source );
功能:将源字符串的副本追加到目标字符串。目的地的终止空字符被源的第一个字符覆盖,并且在目的地中由两个字符串串联而成的新字符串的末尾包含一个空字符。
注意:
1.源字符串必须以'\0'结束
2. 目标字符串中也得有\0,否则没办法知道追加从哪里开始
3. 目标空间必须有足够的大,能容纳下源字符串的内容
4. 目标空间必须可修改
5.1 strcat的使用
int main()
{char arr1[20] = "abcdef";char arr2[20] = "abcda";char* ret = strcat(arr1, arr2);for (int i = 0; i < 20; i++){printf("%c", arr1[i]);}return 0;
}
5.2 模拟实现strcat
char* my_strcat(char* p1, const char* p2)
{while (*p1 != '\0'){p1++;}while (*p2 != '\0'){*p1 = *p2;p1++;p2++;}*p1 = *p2;return p1;
}
int main()
{char arr1[20] = "abcdef";char arr2[20] = "abcda";char* ret = my_strcat(arr1, arr2);for (int i = 0; i < 20; i++){printf("%c", arr1[i]);}return 0;
}
6. strcmp 函数
char* strcat(const char * destination, const char * source );
功能:比较每个字符串的第一个字符。如果它们彼此相等,则继续比较下去,直到字符不同或到达终止空字符为止。
注意:
1. 第一个字符串大于第二个字符串,则返回大于0的数字
2. 第一个字符串等于第二个字符串,则返回0
3. 第一个字符串小于第二个字符串,则返回小于0的数字
比较方法:比较两个字符串中对应位置上字符ASCII码值的大小。
6.1 strcmp的使用
int main()
{char arr1[] = "abcdef";char arr2[20] = "abcda";int ret = strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}
6.2 模拟实现strcmp
int my_strcmp(const char* p1, const char* p2)
{while (*p1 == *p2){if (*p1 == '\0')return 0;p1++;p2++;}if (*p1 > *p2)return 1;elsereturn -1;
}
int main()
{char arr1[] = "abcdef";char arr2[20] = "abcda";int ret = my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}
7. strncpy函数
char * strncpy ( char * destination, const char * source, size_t num );
功能:将源字符串的第一个num字符复制到目标字符串。如果在num字符被复制之前找到了源字符串的结尾(由null字符表示),则用零填充,直到向其总共写入num字符为止。
注意:
1.拷⻉num个字符从源字符串到⽬标空间。
2. 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
7.1 strncpy 的使用
int main()
{char arr1[] = "world";char arr2[20] = "hello";strncpy(arr1, arr2, 3);//当超过字符串长度时,添加'\0'printf("%s", arr1);return 0;
}
8.strncat 函数
char * strncat ( char * destination, const char * source, size_t num );
功能:将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符。如果source 指向的字符串的⻓度小于于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。
8.1 strncat 的使用
int main()
{char arr1[20] = "world";char arr2[20] = "hello";strncat(arr1, arr2, 3);//会追加\0printf("%s", arr1);return 0;
}
9. strncmp 函数
int strncmp ( const char * str1, const char * str2, size_t num );
功能:⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不一样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0。
9.1 strncmp 的使用
int main()
{char arr1[20] = "world";char arr2[20] = "hello";int ret = strncmp(arr1, arr2, 3);//会追加\0printf("%d", ret);return 0;
}
10. strstr 函数
char * strstr ( const char * str1, const char * str2);
功能:函数返回字符串str2在字符串str1中第⼀次出现的位置,字符 串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。
10.1 strstr 的使用
int main()
{char arr1[] = "i think you ";char arr2[] = "think";char* ret = strstr(arr1, arr2);if (ret != NULL)printf("%s\n", ret);elseprintf("没有找到\n");return 0;
}
10.2 模拟实现strstr
char* my_strstr(char* p1, char* p2)
{if (*p2 == '\0'){return NULL;}char* cur = p1;while (*cur != '\0'){char* p3 = cur;char* p4 = p2;while (*p3 == *p4){p3++;p4++;}if (*p4 == '\0'){return p2;}cur++;}return NULL;
}
int main()
{char arr1[] = "I think you ";char arr2[] = "think";char* ret = my_strstr(arr1, arr2);if (ret != NULL)printf("%s\n", ret);elseprintf("没有找到\n");return 0;
}
11. strtok 函数
char * strtok ( char * str, const char * sep);
注意:
1.sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合
2. 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。
3.strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容 并且可修改。)
4. strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串 中的位置。
5. strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标 记。
6. 如果字符串中不存在更多的标记,则返回 NULL 指针。
11.1 strtok 的使用
int main()
{char arr[] = "192.168.6.111";char* sep = " .";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}
12. strerror 函数
char * strerror ( int errnum );
功能:strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明 的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应 的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
12.1 strerror 的使用
#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}
打印结果:
补充:与这个函数功能比较像的函数还有perror函数,prrror函数是直接将错误信息打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{FILE* pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)perror("Error opening file unexist.ent");return 0;
}
打印结果:
相关文章:

C语言--字符函数与字符串函数
大家好,我是残念,希望在你看完之后,能对你有所帮助,有什么不足请指正!共同学习交流 本文由:残念ing 原创CSDN首发,如需要转载请通知 个人主页:残念ing-CSDN博客,欢迎各位…...
整理了一些热门、含免费次数的api,分享给大家
IP归属地-IPv4区县级:根据IP地址查询归属地信息,包含43亿全量IPv4,支持到中国地区(不含港台地区)区县级别,含运营商数据。IP应用场景- IPv4:IPv4应用场景是获取IP场景属性的在线调用接口&#x…...
Wireshark在网络性能调优中的应用
第一章:Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧:过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章:网络协议分析 2.1 网络协议分析:TCP、UDP、ICMP等 2.2 高级协议分析:HTTP…...

关于设计师的自我评价(合集)
设计师的自我评价篇一 本人接受过正规的美术教育,具有较好的美术功底及艺术素养,能够根据公司的需要进行设计制作,熟练掌握多种电脑制作软件,能够高效率地完成工作。本人性格开朗、思维活跃、极富创造力,易于沟通&…...

Hudi Clustering
核心概念 Hudi Clustering对于在数据写入和读取提供一套相对完善的解决方案。它的核心思想就是: 在数据写入时,运行并发写入多个小文件,从而提升写入的性能;同时通过一个异步(也可以配置同步,但不推荐&…...

通过与 Team Finance 整合,Casper Network 让 Token 的创建、部署更加高效
随着 Team Finance 整合到 Casper 系统中,Token 创建的过程变得更加迅速而简便。Casper Network 的方案正在使代币的创建变得易于访问与调整,这将让任何有创意和业务理念的人能够以高效、可信的方式,更快速、安全地在 Casper 上推出他们的项目…...

Linux软件管理rpm和yum
rpm方式管理 rpm软件包名称: 软件名称 版本号(主版本、次版本、修订号) 操作系统 -----90%的规律 #有依赖关系,不能自动解决依赖关系。 举例:openssh-6.6.1p1-31.el7.x86_64.rpm 数字前面的是名称 数字是版本号:第一位主版本号,第二位次版本…...
uart和usart的区别
UART 通用异步收发器,一般来说,在单片机上,名为UART的接口只能用于异步串行通信。 USART 名为USART的接口既可用于同步串行通信,也可用于异步串行通信。...

原生微信小程序-使用 阿里字体图标 详解
步骤一 1、打开阿里巴巴矢量图标库 网址:iconfont-阿里巴巴矢量图标库 2、搜索字体图标,鼠标悬浮点击添加入库 3、按如下步骤添加到自己的项目 步骤二 进入微信开发者工具 1、创建 fonts文件夹 > iconfont.wxss 文件,将刚才的代码复制…...

机器学习 | 机器学习基础知识
一、机器学习是什么 计算机从数据中学习规律并改善自身进行预测的过程。 二、数据集 1、最常用的公开数据集 2、结构化数据与非结构化数据 三、任务地图 1、分类任务 Classification 已知样本特征判断样本类别二分类、多分类、多标签分类 二分类:垃圾邮件分类、图像…...

OpenHarmony鸿蒙原生应用开发,ArkTS、ArkUI学习踩坑学习笔记,持续更新中。
一、AMD处理器win10系统下,DevEco Studio模拟器启动失败解决办法。 结论:在BIOS里面将Hyper-V打开,DevEco Studio模拟器可以成功启动。 二、ArkTS自定义组件导出、引用实现。 如果在另外的文件中引用组件,需要使用export关键字导…...
RHCE8 资料整理(十)二
RHCE8 资料整理 第 31 章 变量的使用(一)31.1 手动定义变量31.2 变量文件31.3 字典变量31.4 列表变量31.5 数字变量的运算31.6 注册变量31.7 facts变量 第 31 章 变量的使用(一) 31.1 手动定义变量 通过vars来定义变量ÿ…...

CUDA 学习记录2
1.是否启用一级缓存有什么影响: 启用一级缓存(缓存加载操作经过一级缓存):一次内存十五操作以128字节的粒度进行。 不启用一级缓存(没有缓存的加载不经过一级缓存):在内存段的粒度上ÿ…...

探索Qt 6.3:了解基本知识点和新特性
学习目标: 理解Qt6.3的基本概念和框架:解释Qt是什么,它的核心思想和设计原则。学会安装和配置Qt6.3开发环境:提供详细的步骤,让读者能够顺利安装和配置Qt6.3的开发环境。掌握Qt6.3的基本编程技巧:介绍Qt6.…...

持续集成交付CICD:基于 GitLabCI 与 JenkinsCD 实现后端项目发布
目录 一、实验 1. GitLabCI环境设置 2.优化GitLabCI共享库代码 3.JenkinsCD 发布后端项目 4.再次优化GitLabCI共享库代码 5.JenkinsCD 再次发布后端项目 一、实验 1. GitLabCI环境设置 (1)GitLab给后端项目添加CI配置路径 (2…...

一些好用的VSCode扩展
可以在扩展这里直接搜索需要的扩展,点击安装即可。 1.Chinese 中文扩展,就是说虽然咱们懂点英语,但还是中文看着方便 2.Auto Rename Tag 当你重命名一个HTML 标签时,会自动重命名与他配对的HTML 标签 当你选择h4这个标签时&…...

3dsmax渲染太慢,用云渲染农场多少钱?
对于许多从事计算机图形设计的创作者来说,渲染速度慢是一个常见问题,尤其是对于那些追求极致出图效果的室内设计师和建筑可视化师,他们通常使用3ds Max这样的工具,而高质量的渲染经常意味着长时间的等待。场景复杂、细节丰富&…...

JVM-9-Class类文件的结构
Java技术能够一直保持着非常良好的向后兼容性,Class文件结构的稳定功不可没。 Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中。 Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,…...
Redis持久化,性能管理
Redis高可用主要通过以下几种方式来实现:单机、主从复制、哨兵模式、和集群模式。这些方式都旨在提高系统的稳定性和可用性,特别是在面对服务器故障或其他问题时。 持久化: 在数据库和缓存系统中,持久化是指将数据保存在存储介质&…...

linux(centos7)离线安装mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar
1. 卸载mariadb相关rpm # 查找 rpm -qa|grep mariadb rpm -qa|grep mysql# 卸载 rpm -e --nodeps mariadb... rpm -e --nodeps mysql...2. 删除mysql相关文件 # 查找 find / -name mysql# 删除 rm -rf /var/lib/mysql...3. 查看是否有相关依赖,没有需安装 rpm -q…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...