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

news2024/11/15 20:02:23

一.求字符串长度

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 ——追加后的arr1
	while (*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函数会将两个字符串的每个字符依次比较
	//若出现不相等则停止比较
	//前一个操作符的元素大于后一个操作符的元素,则会输出一个大于零的整数
	//前一个操作符的元素小于后一个操作符的元素,则会输出一个小于零的整数、
	//等于则输出0
	if (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);  //所以除第一次调用,多次调用时不需要传入参数,所以传入NULL
	printf("%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.coloradmin.cn/o/1143497.html

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

相关文章

如何公网远程访问OpenWRT软路由web界面

文章目录 1.openWRT安装cpolar2.配置远程访问地址3.固定公网地址 简单几步实现在公网环境下远程访问openWRT web 管理界面&#xff0c;使用cpolar内网穿透创建安全隧道映射openWRT web 界面面板443端口&#xff0c;无需公网IP&#xff0c;无需设置路由器。 1.openWRT安装cpola…

linux上java -jar方式运行项目及输出文件nohup.out的清理, linux上定时器的用法

linux上java -jar方式运行项目及输出文件nohup.out的清理&#xff0c; linux上定时器的用法 linux上java -jar方式运行定期自动清理nohup.out文件的内容**验证**定时器crontab使用时注意事项 linux上java -jar方式运行 参考&#xff1a;https://blog.csdn.net/qq_42169450/arti…

聚焦AIGC落地,八仙过海,谁更神通?

【科技明说 &#xff5c; 重磅专题开篇】 从AI高谈阔论的概念&#xff0c; 到AI真金白银的投资&#xff0c;再到AI因ChatGPT大模型的升温&#xff0c;每一次技术带动产业的革新&#xff0c;都离不开不了两样东西的驱动。一是此起彼伏的技术迭代&#xff0c;二是不计后果的资本…

前端重新部署如何通知用户更新

标题解决方案 常用的webSocket解决方案 webSocket; 大致逻辑思考应该是前端在部署好后向服务器发送一个状态变更通知&#xff1b;服务器接收后主动向前端push&#xff1b;前端通过心跳检测&#xff0c;接收到相关更新时弹出提示&#xff0c;让用户确认更新&#xff1b; 缺点&a…

IT新人如何在职场弯道超车?强推荐考取当下最有价值的云计算认证证书!

疯狂的裁员&#xff01;股价降低&#xff01;在美国&#xff0c;一股寒冷的创业寒流正在席卷而来。不只是硅谷进入了冬天&#xff0c;国内的传统互联网寒潮也凛冽地来了。在传统 IT体系结构逐渐式微、产业规模不断缩小的情况下&#xff0c;许多 IT工程师都面临着下岗、跳槽等问…

UVa524 Prime Ring Problem(素数环)

1、题目 2、题意 输入正整数 n n n&#xff0c;把整数1,2,3&#xff0c;…&#xff0c;n 组成一个环&#xff0c;使得相邻两个整数之和均为素数。输出时从整数 1开始逆时针排列。同一个环应恰好输出一次。 n ≤ 16 n \le 16 n≤16。 3、分析 由模型不难得到&#xff1a;每个…

Python异步编程小解一

Python异步编程 什么是异步&#xff0c;为什么是异步&#xff1f; 异步&#xff0c;意指你不用等到某个条件达成再去做某事&#xff0c;比如&#xff1a;你不用等到一切都准备好了才开始跳槽&#x1f415;.那么在 多线程 存在的情况下&#xff0c;我们为什么还要把目光投向 异…

Kafka - 3.x 文件存储不完全指北

文章目录 Topic数据的存储机制演示基本信息使用kafka-run-class.sh查看index内容使用kafka-run-class.sh查看log内容 index文件和log文件详解日志存储参数配置文件清理策略综述清理策略1&#xff09;delete策略2&#xff09;compact日志策略 高效读写的原因 Topic数据的存储机制…

Glide原理

本文基于Carson整理 1.简介 相比其他几种图片加载框架&#xff0c;Glide性能最好。这得益于其高效的图片缓存策略 其还有多样化的媒体格式加载&#xff1a;如GIF、Video&#xff0c;对于商城首页需展示丰富样式、信息的页面需求来说&#xff0c;也是必不可少的。 2.加载原理…

【数智化人物展】洞隐科技联合创始人兼CEO董志刚:数智化转型的核心是应用新技术打造新型的文化、组织和商业模式...

董志刚 本文由洞隐科技联合创始人兼CEO董志刚投递并参与《2023中国企业数智化转型升级先锋人物》榜单/奖项评选。 数据智能产业创新服务媒体 ——聚焦数智 改变商业 在数字化日益渗透的今天&#xff0c;“释放数字价值&#xff0c;驱动智能转型”已逐渐成为企业转型与创新的关…

Vue插件的使用

一、插件的定义 &#xff08;一&#xff09;创建plugin.js文件 文件名可以自定义&#xff0c;但是行业内默认使用plugin作为文件名&#xff0c;该文件和main.js是平级的。 &#xff08;二&#xff09;编写对象中的install方法 install方法能够接收一个参数&#xff0c;就是…

【go】两数求和

文章目录 题目代码解法2 代码仓库 题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案…

5款在线JavaScript加密混淆工具

5款常用、好用的在线JavaScript加密混淆工具&#xff0c;网址请从截图中查看。 1、jscrambler 2、JShaman 3、javascriptobfuscator 4、freejsobfuscator 5、jjencode

【PyQt】调整子控件的层级以调整绘制的先后顺序

简述 qt中貌似没有直接设置z序的函数&#xff0c;但对应的有其他调整z序的方法&#xff1a; QWidget.raise_()&#xff1a;置顶 QWidget.lower()&#xff1a;置底 QWidget.stackUnder(wid)&#xff1a;置于指定控件之下 其中关键函数是QWidget.stackUnder(wid)&#xff0c;利…

phpstorm2022.3.3和xdebug 3 调试代码记录

有鉴于之前使用log日志调试代码&#xff0c;或者var_dump()调试代码太慢了&#xff0c;系统出了问题排查效率低下。最终决定使用xdebug工具提高效率。总结如下&#xff1a; 1. xdebug版本要和phpstorm兼容&#xff0c; 这里使用xdeubug 3.1.6&#xff0c;phpstorm 2022.3.3 (破…

nvm的安装和使用

nvm用途 nvm是用来管理node版本的,安装成功之后可以去切换自己的node版本,就不需要通过安装卸载不同版本的node包 下载与安装 下载地址是https://github.com/coreybutler/nvm-windows/releases 下载nvm-setup.zip,然后安装就可以了 默认路径是C:\Users\wangjingtao\AppData\…

实现成绩发布的高效与便捷

老师们想不想告别繁琐的手动操作&#xff0c;简单省心的发布和查询考试成绩&#xff1f;今天分享的这个方法&#xff0c;可以让学生和家长自主查询成绩&#xff0c;是不是感觉超级方便呢&#xff1f;我来给各位老师讲解一下什么是成绩查询系统吧&#xff01; 成绩查询系统 成绩…

Reflect 对象的创建目的

目录 前言 逻辑 代码示例 使用 Reflect 操作属性 使用 Reflect 检查属性是否存在 使用 Reflect 创建代理 用法 结论 参考资料 前言 Reflect是JavaScript中的一个内置对象&#xff0c;它提供了一组用于访问对象属性和执行对象方法的方法。Reflect的设计目的是为了在语…

IDEA部署SSM项目mysql数据库MAVEN项目部署教程

如果 SSM 项目是基于 Maven 构建的&#xff0c;则需要配置 maven 环境&#xff0c;否则跳过这一步 步骤一&#xff1a;配置 Maven 第一步&#xff1a;用 IDEA 打开项目&#xff0c;准备配置 maven 环境 &#xff0c;当然如果本地没有提前配置好 maven&#xff0c;就用 IDEA 默…

多线程面试相关知识点

文章目录 (一) 进程线程和协程的区别创建线程的4种方式1. 继承Thread类2. 实现runnable接口3. 实现Callable接口4. 线程池创建 runnable 和 callable 有什么区别线程的 run()和 start()有什么区别&#xff1f;线程之间的状态变化notify()和 notifyAll()有什么区别&#xff1f;j…