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

文章目录

    • 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.mfbz.cn/a/188353.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTA-GAN:基于生成对抗性网络的主动脉和颈动脉非集中CT血管造影 CT到增强CT的合成技术

Generative Adversarial Network–based Noncontrast CT Angiography for Aorta and Carotid Arteries 基于生成对抗性网络的主动脉和颈动脉非集中CT血管造影背景贡献实验方法损失函数Thinking 基于生成对抗性网络的主动脉和颈动脉非集中CT血管造影 https://github.com/ying-f…

4-20mA高精度采集方案

下载链接&#xff01;https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247557466&idx1&snb5a323285c2629a41d2a896764db27eb&chksmfcfaf28dcb8d7b9bb6211030d9bda53db63ab51f765b4165d9fa630e54301f0406efdabff0fb&token976581939&langzh_CN#rd …

kafka精准一次、事务、幂等性

Kafka事务 消息中间件的消息保障的3个级别 At most once 至多一次。数据丢失。At last once 至少一次。数据冗余Exactly one 精准一次。好&#xff01;&#xff01;&#xff01; 如何区分只要盯准提交位移、消费消息这两个动作的时机就可以了。 当&#xff1a;先消费消息、…

计算机中由于找不到vcruntime140.dll无法继续执行代码无法打开软件怎么解决分享

关于如何解决vcruntime140.dll无法继续执行代码的6个教程。在这个科技日新月异的时代&#xff0c;电脑已经是我们日常和工作中必不可少的电子产品&#xff0c;然后我们在使用过程中经常会遇到不一样的问题&#xff0c;比如vcruntime140.dll文件丢失&#xff0c;那么vcruntime14…

selenium的基础语法

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️山水速疾来去易&#xff0c;襄樊镇固永难开 ☁️定位页面的元素 参数:抽象类By里…

实验题【网关设置+VRRP+OSPF】(H3C模拟器)

嘿&#xff0c;这里是目录&#xff01; ⭐ H3C模拟器资源链接1. 实验示意图2. 要求和考核目标3. 当前配置3.1 PC1、PC2、PC3、PC4和PC5配置3.2 SW配置3.2.1 SW2配置3.2.2 SW3配置3.2.3 SW4配置3.2.4 SW1配置 3.2. R配置3.2.1 R1配置3.2.2 R2配置 ⭐ H3C模拟器资源链接 H3C网络…

Cesium-terrain-builder编译入坑详解

本以为编译cesium-terrian-tools编译应该没那么难&#xff0c;不想问题重重&#xff0c;不想后人重蹈覆辙&#xff0c;也记录下点点滴滴。 目前网上存在的cesium代码版本主要有两个分支&#xff1a; 原始网站【不能生成layer文件&#xff0c;且经久不更新&#xff0c;使用gdal…

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

PPT演示文稿操作题 提示:PPT部分操作题 将第2~第4张幻灯片背景效果设为渐变预置的“雨后初晴”效果(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…

【负载均衡】这些内容你需要知道下

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

Golang并发模型:Goroutine 与 Channel 初探

文章目录 goroutinegoexit() channel缓冲closerangeselect goroutine goroutine 是 Go 语言中的一种轻量级线程&#xff08;lightweight thread&#xff09;&#xff0c;由 Go 运行时环境管理。与传统的线程相比&#xff0c;goroutine 的创建和销毁的开销很小&#xff0c;可以…

Python基于jieba+wordcloud实现文本分词、词频统计、条形图绘制及不同主题的词云图绘制

目录 序言&#xff1a;第三方库及所需材料函数模块介绍分词词频统计条形图绘制词云绘制主函数 效果预览全部代码 序言&#xff1a;第三方库及所需材料 编程语言&#xff1a;Python3.9。 编程环境&#xff1a;Anaconda3&#xff0c;Spyder5。 使用到的主要第三方库&#xff1a;…

【Leetcode】【实现循环队列】【数据结构】

代码实现&#xff1a; typedef struct {int front;int back;int k;int* a;} MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->frontobj->back; }bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->back1)%(obj->…

位图和布隆过滤器

目录 一. 位图 1.题目&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中&#xff1f; 2.解析题目&#xff1a; 3.位图 4.代码以及测试 5.其他题目 二.布隆过滤器 1.介绍 2.实现 …

Vue服务端渲染——同构渲染

Vue.js 可以用于构建客户端应用程序&#xff0c;组件的代码在浏览器中运行&#xff0c;并输出 DOM 元素。同时&#xff0c;Vue.js 还可以在 Node.js 环境中运行&#xff0c;它可以将同样的组件渲染为字符串并发送给浏览器。这实际上描述了 Vue.js 的两种渲染方式&#xff0c;即…

【云原生】什么是 Kubernetes ?

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

电脑技巧:U盘运用小技巧,提升U盘运用寿命

目录 1、注意清洁&#xff0c;防止污染 2、别随意插拔 3、文件多时分段写入 4、U盘传输数据中切记拔掉U盘 5、建议不要长期将U盘插在电脑上 6、杜绝别频繁将U盘格式化 7、U盘中毒怎么办 U盘是大家日常办公经常用得到的便携式文件储存工具&#xff0c;因为其小巧便携、方…

5.3每日一题(不确定正负号的级数敛散性:和一个正项级数比较判定)

比较判别法和比较判别法的极限形式是对正项级数而言的&#xff0c;若一个级数和p级数比较&#xff0c;结果>0&#xff0c;则同敛散&#xff1b;若结果<0&#xff0c;则结果乘以-1 结果又同敛散了&#xff1b;所以只要比值不等于0&#xff0c;则同敛散&#xff1b; 所以当…

鸿蒙(HarmonyOS)应用开发——生命周期、渲染控制、状态管理装饰器

生命周期 任何程序都是有一定的生命周期的。生命周期是记录从产生到销毁的过程&#xff1b;如果熟悉前端vue.js的话&#xff0c;就可以很好的理解生命周期。 自定义组件生命周期 ArkTS中&#xff0c;自定义组件提供了两个生命周期函数&#xff1a;aboutToAppear() 和aboutTo…

代码随想录算法训练营第四十七天|198. 打家劫舍、213. 打家劫舍II、337. 打家劫舍III

LeetCode 198. 打家劫舍 题目链接&#xff1a;198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 第一次打家劫舍&#xff0c;来个简单一些的&#xff0c;无非就是偷了当前这家偷不了下一家&#xff0c;因此dp[n]代表&#xff0c;偷前n家的时候所能偷到的最高金额&#x…
最新文章