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

一.求字符串长度

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;

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

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

相关文章

Linux常见问题解决操作(yum被占用、lsb无此命令、Linux开机进入命令界面等)

Linux常见问题解决操作&#xff08;yum被占用、lsb无此命令、Linux开机进入命令界面等&#xff09; 问题一、新安装的Linux使用命令lsb_release提示无此命令&#xff0c;需先安装再使用 Linux安装lsb命令 lsb是Linux Standard Base的缩写&#xff08;Linux基本标准&#xff…

Centos7 安装和配置 Redis 5 教程

在Centos上安装Redis 5&#xff0c;如果是 Centos8&#xff0c;那么 yum 仓库中默认的 redis 版本就是 5&#xff0c;直接 yum install 即可。但如果是 Centos7&#xff0c;yum 仓库中默认的 redis 版本是 3 系列&#xff0c;比较老&#xff1a; 通过 yum list | grep redis 命…

Constellation 介绍:Chainlink 黑客马拉松

在 2020 年&#xff0c;Chainlink 举办了其第一次线上黑客马拉松。当时&#xff0c;DeFi 作为一个类别刚刚开始蓬勃发展&#xff0c;而 NFT 也只是刚刚起步。这次黑客马拉松吸引了来自 45 个国家的 1,000 多名注册参与者&#xff0c;并收到了来自 70 个项目提交。 从那时起&am…

【C++初探:简单易懂的入门指南】一

【C初探&#xff1a;简单易懂的入门指南】一 1. 命名空间1.1 命名空间的定义1.2 命名空间的使用方法 2. C的输入、输出2.1 为什么使用输入、输出要引用一个<iostream>的头文件&#xff1f;2.2 为什么代码里面开放了一个叫std的命名空间2.3 代码中出现的<<和>>…

基于SSM的航班订票管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

SpringBoot使用WebSocket收发实时离线消息

引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> WebScoket配置处理器 import org.springframework.boot.web.servlet.ServletContextI…

JVM面试知识点整理

文章目录 (一) JVM组成JVM组成部分和运行流程从图中可以看出 JVM 的主要组成部分运行流程&#xff1a;程序计数器Java堆虚拟机栈方法区堆栈的区别是什么&#xff1f; (二) 类加载器双亲委派模型类装载的执行过程 (三) 垃圾回收对象什么时候可以被垃圾回收哪些可以作为根对象 垃…

浅谈安科瑞EMS能源管控平台建设的意义-安科瑞 蒋静

摘 要&#xff1a;能源消耗量大、能源运输供给不足、环境压力日趋增加、能耗双控等一系列问题一直困扰着钢铁冶金行业&#xff0c;制约着企业快速稳定健康发展。本文介绍的安科瑞EMS能源管控平台&#xff0c;采用自动化、信息化技术&#xff0c;实现从能源数据采集、过程监控、…

Spring Boot简介

Spring Boot帮助你创建可以运行的独立的、基于Spring的生产级应用程序。 我们对Spring平台和第三方库采取了有主见的观点&#xff0c;这样你就能以最少的麻烦开始工作。 大多数Spring Boot应用程序只需要很少的Spring配置。 你可以使用Spring Boot来创建Java应用程序&#xff…

【Python3】【力扣题】202. 快乐数

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;用哈希集合检测循环。设置集合记录每次结果&#xff0c;判断结果是否为1。若计算结果已在集合中则进入循环&#xff0c;结果一定不为1。 &#xff08;1-1&#xff09;知识点&#xff1a;…

基于SSM和VUE的留守儿童信息管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

关键词搜索1688商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

1688商品列表接口是一个用于获取1688网站上商品列表信息的接口。通过该接口&#xff0c;您可以获取到1688网站上不同类别的商品列表&#xff0c;包括商品的名称、价格、图片等信息。 要使用1688商品列表接口&#xff0c;您需要按照以下步骤进行操作&#xff1a; 登录1688网站…

听力检测为什么要在标准化的隔声屏蔽系统中进行?

作者兰明&#xff0c;医学硕士&#xff0c;听力学博士&#xff0c;听觉健康门诊主任 美国国家研究委员会;;行为、认知和感官科学委员会联合出版的听力损失确定社会保障福利的资格一书中关于测试环境的要求如下&#xff1a; 行动建议4-4 测试环境 听力学评估是在受控的声学环境中…

接口返回响应,统一封装(ResponseBodyAdvice + Result)(SpringBoot)

需求 接口的返回响应&#xff0c;封装成统一的数据格式&#xff0c;再返回给前端。 依赖 对于SpringBoot项目&#xff0c;接口层基于 SpringWeb&#xff0c;也就是 SpringMVC。 <dependency><groupId>org.springframework.boot</groupId><artifactId&g…

使用WebStorm创建和配置TypeScript项目

创建 这里我用的是WebStorm 2019.2.2版本 首先&#xff0c;创建一个空项目 File -> New -> Project->Empty Project生成配置文件 自动配置&#xff1a; 打开终端输入tsc --init&#xff0c;即可自动生成tsconfig.json文件 手动配置&#xff1a; 在项目根目录下新建一…

数据结构与算法之矩阵: Leetcode 48. 旋转矩阵 (Typescript版)

旋转图像 https://leetcode.cn/problems/rotate-image/ 描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1 输入&…

【Docker】Linux网桥连接多个命名空间

veth实现了点对点的虚拟连接&#xff0c;可以通过veth连接两个namespace&#xff0c;如果我们需要将3个或者多个namespace接入同一个二层网络时&#xff0c;就不能只使用veth了。 在物理网络中&#xff0c;如果需要连接多个主机&#xff0c;我们会使用bridge&#xff08;网桥&…

增强常见问题解答搜索引擎:在 Elasticsearch 中利用 KNN 的力量

在快速准确的信息检索至关重要的时代&#xff0c;开发强大的搜索引擎至关重要。 随着大型语言模型和信息检索架构&#xff08;如 RAG&#xff09;的出现&#xff0c;在现代软件系统中利用文本表示&#xff08;向量/嵌入&#xff09;和向量数据库已变得越来越流行。 在本文中&am…

javaweb+mysql的电子书查阅和下载系统

图书分类查看、热门下载、最新上传、站内数据统计。 登陆注册、图书查询、图书详情、图书下载。 身份分为管理员和用户。 源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制

串口占用检测工具

串口占用检测工具 平时需要检测哪个程序占用了串口&#xff0c;下面介绍一款非常方便的工具&#xff0c;它的工具箱里包含一个串口占用检测工具&#xff0c;可以非常方便的检测出来哪个程序占用了串口&#xff0c;并给出程序名和PID。 官网下载地址&#xff1a;http://www.red…