c语言-字符函数和字符串函数详解

news2024/11/19 10:48:06

文章目录

    • 1. 字符分类函数
    • 2. 字符转换函数
    • 3. strlen的使用和模拟实现
    • 4. strcpy的使用和模拟实现
    • 5. strncpy函数的使用
    • 6. strcat的使用和模拟实现
    • 7. strncat函数的使用
    • 8. strcmp的使用和模拟实现
    • 9. strncmp函数的使用
    • 10. strstr的使用和模拟实现
    • 11. strtok函数的使用
    • 12. strerror函数的使用


以下这些字符函数和字符串函数都可以通过这个网站找到详细的介绍:https://legacy.cplusplus.com/

1. 字符分类函数

作用:用于判断一个字符是属于什么类型的字符
头文件:#include<ctype.h>
列举:
在这里插入图片描述

我们这里使用一个 islower 函数判断一个字符是不是字母小写

int islower ( int c );

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。
通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回0。

代码:

#include<ctype.h>
#include<stdlib.h>
int main() {
	char a = getchar();
	if (islower(a))
		printf("小写");
	else
		printf("其他");
	return 0;
}

运行结果:
在这里插入图片描述
其他的类似也这样判断

2. 字符转换函数

还有将字母小写互换大写字符函数,如:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

我们来试试:

#include<ctype.h>
#include<stdlib.h>
int main() {
	char a = getchar();
	if (islower(a)) {
		char b = toupper(a);
		printf("%c\n", b);
	}
	else
		printf("输入的不是小写字母");
	return 0;
}

运行结果:
在这里插入图片描述

3. strlen的使用和模拟实现

参数和返回类型:

 size_t strlen ( const char * str );

1.字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包 含 ‘\0’ )。
2. 参数指向的字符串必须要以 ‘\0’ 结束。
3.注意函数的返回值为size_t,是⽆符号的( 易错 )。
4. strlen的使⽤需要包含头⽂件(string.h)。

使用:

#include<string.h>//包含头文件
int main() {
	char* a = "abcdef";
	size_t  te = strlen(a);//计算字符串中‘\0之前的元素个数,注意返回类型为size_t
	printf("%zd\n", te);//打印
	return 0;
}

运行结果:
在这里插入图片描述

模拟 strlen 函数

1.我们创建一个函数,参数用来接收字符串的首地址,返回类型和strlen一样为 size_t
2.我们设置一个计数器来计算字符个数,通过循环来遍历字符串,每遍历一次计数器就++,直到遇到‘\0’为止

代码:

size_t mn_strlen1(const char* s) {
	//我们不希望改变字符串 所以用const修饰,s用来接收首地址
	int i = 0;//计数器
	assert(s);
	while (*s) {//当*s为'\0'时打破循环
		i++;
		s++;//字符地址++
	}
	return i;//返回
}
int main() {
	char a[] = "abcdef";
	size_t len1 = mn_strlen1(a);
	printf("%zd\n", len1);
	return 0;
}

运行结果:
在这里插入图片描述

4. strcpy的使用和模拟实现

参数和返回类型:

 char* strcpy(char * destination, const char * source );

1.源字符串必须以 ‘\0’ 结束。
2. 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
3.⽬标空间必须⾜够⼤,以确保能存放源字符串。
4.⽬标空间必须可修改。

使用:

#include<string.h>//包含头文件
int main() {
	char a[20] = { 0 };//目标空间一定要够大
	char b[] = "abcdef";//字符串的‘\0'也会拷贝
	char* p = strcpy(a, b);//用p来接收返回来的地址
	printf("%s\n", p);//打印
	return 0;
}

运行结果:
在这里插入图片描述
模拟 strcpy函数
1.我们创建一个函数,参数分别为目标空间的地址和源字符串地址,返回为目标空间的首地址
2.我们可以先创建一个指针变量来记住目标空间的首地址,然后将源字符串中的每一个字符都传到目标空间里直到传完’\0’为止,最后返回目标空间首地址
实现代码:

//strcpy模拟实现
char* mn_strcpy(char* p1, const char* p2) {
	//我们不希望改变字符串p2 所以用const修饰,p1为目标空间的首地址,p2为源字符串首地址
	assert(p1);//防止为NULL
	assert(p2);
	char* p = p1;//保存目标空间首地址
	while (*p1=*p2) {//解引用将*p2的字符赋给*p1
		p1++;//地址加加
		p2++;
	}
	return p;//返回目标空间首地址
 }
int main() {
	char a[20] = { 0 };
	char b[] = "abcdef";
char*p=mn_strcpy(a, b);
	printf("%s\n", p);
	return 0;
}

运行结果:

在这里插入图片描述

5. strncpy函数的使用

参数和返回类型:

`char * strncpy ( char * destination, const char * source, size_t num );

1.拷⻉num个字符从源字符串到⽬标空间。
2.如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

使用:

int main() {
	char a[20] = {0};
	char b[] = "abcde";
	printf("%s\n", strncpy(a, b,3));//只拷贝三个
	return 0;
}

运行结果:
在这里插入图片描述

6. strcat的使用和模拟实现

参数和返回类型:

char* strcat(char * destination, const char * source );

作用:将源字符串连接到目标字符串上
1.源字符串必须以 ‘\0’ 结束。
2.⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
3.⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
4.⽬标空间必须可修改。

使用:

#include<string.h>//包含头文件
int main() {
	char a[20] = "qwe";//目标空间一定要够大
	char b[] = "abcdef";
	char* p = strcat(a, b);//用p来接收返回来的地址
	printf("%s\n", p);//打印
	return 0;
}

运行结果:
在这里插入图片描述
模拟strcat函数

1.我们创建一个函数,参数分别为目标空间的地址和源字符串地址,返回为目标空间的首地址
2.我们先创建一个指针变量来储存目标空间的首地址,再用循环来遍历目标空间的字符串直到找到\0’,停止
3.将源字符串中的每一个字符都传到目标空间里直到传完’\0’为止,最后返回目标空间首地址

实现代码:

//strcat模拟
char* nm_strcat(char* p1, const char* p2) {
	//我们不希望改变字符串p2 所以用const修饰,p1为目标空间的首地址,p2为源字符串首地址
	char* p = p1;//保存目标空间首地址
	assert(p1);
	assert(p2);
		while (*p1)//遍历*p直到找到‘/0’
			p1++;
		while (*p1=*p2) {///解引用将*p2的字符赋给*p1
		p1++;
		p2++;
	}
	return p;//返回目标空间首地址
}
int main() {
	char a[20] ="grr";
	char b[] = "abcdef";
	char*p=nm_strcat(a, b);
	printf("%s\n", p);
	return 0;
}

运行结果:
在这里插入图片描述

7. strncat函数的使用

参数和返回类型:

char * strncat ( char * destination, const char * source, size_t num );

1.将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符
2.如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾

使用:

int main() {
	char a[20] = "xxx";
	char b[] = "abcde";
	printf("%s\n", strncat(a, b,3));

	return 0;
}

运行结果:
在这里插入图片描述

8. strcmp的使用和模拟实现

参数和返回类型:

int  strcmp(comst char * destination, const char * source );

第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
第⼀个字符串等于第⼆个字符串,则返回0
第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

使用:

#include<string.h>//包含头文件
int main() {
	char a[] = "abfa";//
	char b[] = "abqc";
	int t = strcmp(a, b);
		if (t == 0)
		printf("a=b");
	else if (t > 0)
		printf("a>b");
	else
		printf("a<b");
	return 0;
}

比较过程图:
在这里插入图片描述
运行结果:
在这里插入图片描述
模拟strcmp函数

1.我们创建一个函数,参数分别接收两个字符串的首地址,返回 int的数据
2.通过循环将两个字符串一一对比,直到出现不相等或者都为‘\0’的情况

代码实现:

int mn_strcmp(const char* p1, const char* p2) {
	//	我们不希望改变字符串p2 和p1所以用const修饰,p1为目标空间的首地址,p2为源字符串的首地址
	assert(p1);//防止为NULL
	assert(p2);
	while (*p1 == *p2) {//相等就继续比较
		if (*p1 == '\0')//当双方都是\0时就是两字符串相等
			return 0;
		p1++;
		p2++;
	}
	return *p1 - *p2;//p1>pp2时返回正值,否则反之
}
int main() {
	char* a = "ger";
	char* b = "ger";
	int t = mn_strcmp(a, b);
	if (t == 0)
		printf("a=b");
	else if (t > 0)
		printf("a>b");
	else
		printf("a<b");
	return 0;
}

运行结果:
在这里插入图片描述

9. strncmp函数的使用

参数和返回类型:

 int strncmp ( const char * str1, const char * str2, size_t num );

⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀
样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0

使用:

int main() {
	char* a = "gerqq";
	char* b = "gera";
	int t = strncmp(a, b,3);//比较前三个字符
	if (t == 0)
		printf("a=b");
	else if (t > 0)
		printf("a>b");
	else
		printf("a<b");
	return 0;
}

运行结果:
在这里插入图片描述

10. strstr的使用和模拟实现

参数和返回类型:

char * strstr ( const char * str1, const char * str2);

作用:查找str1中str2
1.函数返回字符串str2在字符串str1中第⼀次出现的位置
2.字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志

使用:

#include<string.h>//包含头文件
int main() {
	char a[] = "abcdfa";//
	char b[] = "cd";//
	char* p = strstr(a, b);//在a字符串中找b字符串,找到之后返回找到时在a的地址
	printf("%s\n", p);
	return 0;
}

运行结果:
在这里插入图片描述
模拟strsstr函数

1.我们创建一个函数,参数分别接收两个字符串的首地址,返回 查找成功时的地址
2.第一种情况就是查找的字符串为NULL此时我们直接返回目标字符串,第二我们需要设置三个指针,其中一个记录目标字符串移动到的位置,还有两个分别进行遍历,找到相同就继续,不同就跳出,跳出后记录指针就++,再进行下一次遍历,直到找到源字符串的’\0‘就算查找成功,不然就找不到

代码实现:

char* mn_strstr(const  char* p1, const char* p2) {
	assert(p1);//	我们不希望改变字符串p2 和p1所以用const修饰,p1为目标空间的首地址,p2为源字符串的首地址
	if (!*p2)//源字符串为NILL时直接返回p1
		return p1;
	char* con = p1;//记录指针,从第一个位置开始
	char* s1 = NULL;//空
	char* s2 = NULL;//
	while (*con) {//当将目标字符串都找一次还没有就返回NULL
		s1 = con;//目标字符移动指针
		s2 = p2;//源字符移动指针
		while ((*s1 == *s2) && *s2) {//对比,当s2为'\0'时结束
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return con;
		con++;
	}
	return NULL;
}

int main() {
	char* a = "cdf";
	char* b = "cqf";
	char* p = mn_strstr(a, b);
	if (!p)
		printf("找不到\n");
	else
		printf("%s\n", p);
	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 指针

使用:

#include <stdio.h>
#include <string.h>
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函数就可以将错误对应的错误信息字符串的地址返回。

使用:

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

运行结果:
在这里插入图片描述

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!

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

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

相关文章

【云原生】什么是 Kubernetes ?

什么是 Kubernetes &#xff1f; Kubernetes 是一个开源容器编排平台&#xff0c;管理着一系列的 主机 或者 服务器&#xff0c;它们被称作是 节点&#xff08;Node&#xff09;。 每一个节点运行了若干个相互独立的 Pod。 Pod 是 Kubernetes 中可以部署的 最小执行单元&#x…

JAVA之异常详解

1. 异常的概念与体系结构 1.1 异常的概念 在Java中&#xff0c;将程序执行过程中发生的不正常行为称为异常 1. 算术异常 public class Test {public static void main(String[] args) {System.out.println(10/0);} } 因为 0 不能当被除数&#xff0c;所以报出了异常&#…

java协同过滤算法 springboot+vue游戏推荐系统

随着人们生活质量的不断提高以及个人电脑和网络的普及&#xff0c;人们的业余生活质量要求也在不断提高&#xff0c;选择一款好玩&#xff0c;精美&#xff0c;画面和音质&#xff0c;品质优良的休闲游戏已经成为一种流行的休闲方式。可以说在人们的日常生活中&#xff0c;除了…

高级驾驶辅助系统 (ADAS)介绍

随着汽车技术持续快速发展,推动更安全、更智能、更高效的驾驶体验一直是汽车创新的前沿。高级驾驶辅助系统( ADAS ) 是这场技术革命的关键参与者,是 指集成到现代车辆中的一组技术和功能,用于增强驾驶员安全、改善驾驶体验并协助完成各种驾驶任务。它使用传感器、摄像头、雷…

vue开发中遇到的问题记录

文章目录 前言1、css 即时使用了scoped子组件依然会生效2、路由配置如果出现重复name&#xff0c;只会生效最后一个&#xff0c;且前端的路由无效3、组件之间事件传递回调需要先定义emits: []&#xff0c;不然会警告提示总结如有启发&#xff0c;可点赞收藏哟~ 前言 1、css 即…

DBeaver连接Oracle时报错:Undefined Error

连接信息检查了很多遍&#xff0c;应该是没问题的&#xff0c;而且驱动也正常下载了&#xff0c;但是就是连不上。 找了好久&#xff0c;终于找到一个可用的方式了&#xff0c;记录一下。 在安装目录修改dbeave.ini文件&#xff0c;最后一行添加 -Duser.nameTest。重启就可以…

鸿蒙开发板——环境搭建(南派开发)

概述 为了帮大家理清楚鸿蒙开发的套路&#xff0c;我们从头再梳理一遍相关的脉络。并为大家总结一些重点性的内容。在介绍OpenHarmony特性前&#xff0c;需要大家先明确以下两个基本概念&#xff1a; 子系统 OpenHarmony整体遵从分层设计&#xff0c;从下向上依次为&#xf…

FPGA模块——SPI协议(读写FLASH)

FPGA模块——SPI协议&#xff08;读写FLASH&#xff09; &#xff08;1&#xff09;FLASH芯片 W25Q16BV&#xff08;2&#xff09;SPI协议&#xff08;3&#xff09;芯片部分命令1.Write Enable&#xff08;06h&#xff09;2.Chip Erase (C7h / 60h)3.写指令&#xff08;02h&am…

TI 毫米波雷达开发系列之mmWave Studio 和 Visuiallizer 的异同点雷达影响因素分析

TI 毫米波雷达开发之mmWave Studio 和 Visuiallizer 的异同点 引入整个雷达系统研究的目标分析影响这个目标的因素硬件影响因素 —— 雷达系统的硬件结构&#xff08;主要是雷达收发机&#xff09;AWR1642芯片硬件系统组成MSS 和 DSS 概述MSS 和 DSS 分工BSS的分工AWR1642 组成…

crontab计划任务

银河麒麟v10服务器版和桌面版执行周期计划任务分为两类&#xff1a;系统任务调度和用户任务调度。系统任务是由 cron (crond) 这个系统服务来控制的&#xff0c;这个系统服务是默认启动的&#xff0c;通过vim /etc/crontab执行。用户自己设置的计划任务则使用crontab 命令 配置…

Everything进行内网穿透搜索

文章目录 1\. 部署内网穿透1.1. 注册账号1.2. 登录1.3. 创建隧道 2\. 从外网访问Everything 借助cpolar可以让我们在公网上访问到本地的电脑 1. 部署内网穿透 1.1. 注册账号 在使用之前需要先进行注册cpolar cpolar secure introspectable tunnels to localhost 1.2. 登录 C…

【Web】[GKCTF 2021]easycms

直接点击登录按钮没有反应 扫目录扫出来/admin.php 访问 弱口令admin 12345直接登录成功 点开设计--主题--自定义 编辑页头&#xff0c;类型选择php源代码 点保存显示权限不够 设计--组件--素材库 先随便上传一个文件&#xff0c;之后改文件名称为../../../../../system/tmp…

计算机应用基础_错题集_PPT演示文稿_操作题_计算机多媒体技术操作题_文字处理操作题---网络教育统考工作笔记007

PPT演示文稿操作题 提示:PPT部分操作题 将第2~第4张幻灯片背景效果设为渐变预置的“雨后初晴”效果(2)设置幻灯片放映方式

卷积神经网络(Inception-ResNet-v2)交通标志识别

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;2. 导入数据3. 查看数据 二、构建一个tf.data.Dataset1.加载数据2. 配置数据集 三、构建Inception-ResNet-v2网络1.自己搭建2.官方模型 五、设置动态学习率六、训练模型七、模型评…

【小沐学写作】免费在线AI辅助写作汇总

文章目录 1、简介2、文涌Effidit&#xff08;腾讯&#xff09;2.1 工具简介2.2 工具功能2.3 工具体验 3、PPT小助手&#xff08;officeplus&#xff09;3.1 工具简介3.2 使用费用3.3 工具体验 4、DeepL Write&#xff08;仅英文&#xff09;4.1 工具简介4.2 工具体验 5、天工AI…

数组题目:645. 错误的集合、 697. 数组的度、 448. 找到所有数组中消失的数字、442. 数组中重复的数据 、41. 缺失的第一个正数

645. 错误的集合 思路&#xff1a; 我们定义一个数组cnt&#xff0c;记录每个数出现的次数。然后我们遍历数组&#xff0c;从1开始&#xff0c;如果cnt[i] 0 那就说明这个是错误的数&#xff0c;如果 cnt[i] 2&#xff0c;那就说明是重复的数。 代码&#xff1a; class So…

嵌入式虚拟机原理

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

【数据集】全网最全的常见已公开医学影像数据集

目录 一&#xff0c;极市医学数据集汇总 1.CT 医学图像 ​编辑 2.恶性与良性皮肤癌 3.白内障数据集 4.胸部 X 光图像&#xff08;肺炎&#xff09; 5.用于图像增强的内窥镜真实合成曝光过度和曝光不足帧 6.医学家 7.乳房组织病理学图像 8.皮肤癌 MNIST&#xff1a;HA…

芯片安全和无线电安全底层渗透技术

和传统网络安全不同&#xff0c;硬件安全、芯片安全、无线电安全属于网络底层安全的重要细分领域&#xff0c;是网络安全的真正基石&#xff0c;更是国家安全的重要组成部分&#xff0c;“夯实网络底层安全基础&#xff0c;筑牢网络强国安全底座”&#xff0c;是底网安全重要性…

上手 Promethus - 开源监控、报警工具包

名词解释 Promethus 是什么 开源的【系统监控和警报】工具包 专注于&#xff1a; 1&#xff09;可靠的实时监控 2&#xff09;收集时间序列数据 3&#xff09;提供强大的查询语言&#xff08;PromQL&#xff09;&#xff0c;用于分析这些数据 功能&#xff1a; 1&#xff0…