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;
}

打印结果:

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

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

相关文章

Java 数据结构篇-实现二叉搜索树的核心方法

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 二叉搜索树的概述 2.0 二叉搜索树的成员变量及其构造方法 3.0 实现二叉树的核心接口 3.1 实现二叉搜索树 - 获取值 get(int key) 3.2 实现二叉搜索树 - 获取最小…

程序流程图的意义(合集)

程序流程图的意义 1、矩形 作用&#xff1a;一般用作要执行的处理(process)&#xff0c;在程序流程图中做执行框。 在axure中如果是画页面框架图&#xff0c;那么也可以指代一个页面。有时候我们会把页面和执行命令放在同一个流程中做说明&#xff0c;这个时候将两类不同的矩形…

算法(2)——滑动窗口

前言&#xff1a; 步骤及算法模板&#xff1a; 确定两个指针变量&#xff0c;left0,right0; 进窗口&#xff1a; 判断&#xff1a; 出窗口 更新结果 接下来我们的所用滑动窗口解决问题都需要以上几个步骤。 一、长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;L…

Ebullient第一阶段开发小结

一. 简介 距离Ebullient硬件发布已有一段时间&#xff0c;小一个月吧&#xff0c;在这段时间内在努力的编写代码&#xff0c;现在终于完成了第一阶段的功能设计&#xff0c;算是一个小型的样机吧&#xff0c;基本的代码框架基本确定了&#xff0c;相信后续的会快一点(希望如此…

Nodejs 第二十六章(反向代理)

什么是反向代理? 反向代理&#xff08;Reverse Proxy&#xff09;是一种网络通信模式&#xff0c;它充当服务器和客户端之间的中介&#xff0c;将客户端的请求转发到一个或多个后端服务器&#xff0c;并将后端服务器的响应返回给客户端。 负载均衡&#xff1a;反向代理可以根…

二、W5100S/W5500+RP2040之MicroPython开发<DHCP示例>

文章目录 1 前言2 相关网络信息2 .1 简介2.2 DHCP工作原理2.3 DHCP的优点2.4 应用场景 3 WIZnet以太网芯片4 DHCP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 在这个智能硬件和物联网时代&#…

在Python中使用Kafka帮助我们处理数据

Kafka是一个分布式的流数据平台&#xff0c;它可以快速地处理大量的实时数据。Python是一种广泛使用的编程语言&#xff0c;它具有易学易用、高效、灵活等特点。在Python中使用Kafka可以帮助我们更好地处理大量的数据。本文将介绍如何在Python中使用Kafka简单案例。 一、安装K…

C到C++笔记记录

C到C笔记记录 输入(cin) and 输出(cout)bool内联(inline)重载缺省函数哑元引用(&)C动态内存分配笔记扩充&#xff1a; 输入(cin) and 输出(cout) #include<iostream>using namespace std;void main() {int i;//输入 cincin >> i;//输出 coutcout << i &…

浅谈云性能测试的关键要点

随着云计算的广泛应用&#xff0c;云性能测试成为确保云服务质量和性能的关键环节。云性能测试不仅涵盖了传统性能测试的方面&#xff0c;还需要考虑云环境的特殊性。以下是云性能测试的几个关键要点&#xff1a; 1. 模拟真实云环境 云环境具有虚拟化、弹性扩展等特点&#xff…

IDEA tomcat内存不足

-Xms256m -Xmx256m -XX:MaxNewSize256m -XX:MaxPermSize256m

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph API资源对象StorageClass SC的主要作用在于&#xff0c;自动创建PV&#xff0c;从而实现PVC按需自动绑定PV。 下面我们通过创建一个基于NFS的SC来演示SC的作用。 要想使用NFS的SC&#xff0c;还需要安装一个NFS…

Kubernetes 的用法和解析 -- 5

一.企业级镜像仓库Harbo 准备&#xff1a;另起一台新服务器&#xff0c;并配置docker yum源&#xff0c;安装docker 和 docker-compose 1.1 上传harbor安装包并安装 [rootharbor ~]# tar xf harbor-offline-installer-v2.5.3.tgz [rootharbor ~]# cp harbor.yml.tmpl harbor…

不会代码循环断言如何实现?只要6步!

对于使用jmeter工具完成接口测试的测试工程师而言。在工作中&#xff0c;或者在面试中&#xff0c;都会遇到一个问题—— “CSV文档做了一大笔测试数据后&#xff0c;怎么去校验这个结果呢&#xff1f;” 现在大部分测试工程师可能都是通过人工的方法去查看结果&#xff0c;十…

作业--day33

基于UDP的TFTP文件上传 #include <myhead.h>#define PORT 69 #define IP "192.168.125.59"int down(const char *); int up(const char *);int main(int argc, const char *argv[]) {while(1){system("clear");//打印菜单puts("**************…

STM32F407-14.3.12-01使用断路功能

使用断路功能 使用断路功能时&#xff0c;根据其它控制位&#xff08;TIMx_BDTR 寄存器中的 MOE⑨、OSSI⑪ 和 OSSR⑩ 位以及 TIMx_CR2 寄存器中的 OISx⑰ 和 OISxN⑱ 位&#xff09;修改输出使能信号和无效电平。任何情况下&#xff0c;OCx③ 和 OCxN④ 输出都不能同时置为有效…

LD2450-24G人体移动跟踪轨迹雷达模块

文章目录 前言一、LD2450简介特点引脚定义 二、使用步骤上位机使用方法通信协议协议格式数据输出协议 雷达命令配置方式串口解析示例 前言 运动目标跟踪是指在区域内实时跟踪运动目标所在的位置&#xff0c;实现对区域内运动目标测距、测角和测速。LD2450是海凌科24G毫米波雷达…

基于paddlepaddle的FPS最远点采样

什么是FPS最远点采样&#xff1f; 最远点采样&#xff08;Farthest Point Sampling&#xff0c;FPS&#xff09;是一种常用的采样算法&#xff0c;主要用于点云数据&#xff08;如激光雷达点云数据、分子坐标等&#xff09;的采样。 为了方便解释&#xff0c;定义一下待采样点…

深入解析线程安全的Hashtable实现

目录 引言 1. Hashtable简介 2. Hashtable线程安全实现原理 2.1. 锁机制 2.2. 分段锁 2.3. CAS操作 3. 线程安全策略 3.1. 同步方法 3.2. 分段锁优化 3.3. 乐观锁和CAS 4. 性能优化 4.1. 负载均衡 4.2. 惰性加载 5. 注意事项 5.1. 死锁和性能问题 5.2. 内存开销…

嵌入式软件测试(黑盒测试)---三年嵌入式软件测试的理解

文章内容为本人这三年来在嵌入式软件测试&#xff08;黑盒&#xff09;上的一些积累吧&#xff0c;说起来也挺快的&#xff0c;毕业三年的时间就这样过去了&#xff0c;在两家公司工作过&#xff08;现在这家是第二家&#xff09;&#xff0c;这几年的测试项目基本都是围绕着嵌…

第十三章 枚举类型和泛型

枚举类型可以取代以往的常用的定义方式&#xff0c;即将常量封装在类或者接口中&#xff0c;此外它还提供了安全检查功能。枚举类型本质上还剋以类的形式存在。泛型的出现不仅可以让程序员少写一些代码&#xff0c;更重要的是它可以解决类型安全问题。泛型提供了编译时的安全检…