C语言字符函数与字符串函数:编织文字的舞会之梦(上)

欢迎来到白刘的领域   Miracle_86.-CSDN博客

系列专栏  C语言知识

先赞后看,已成习惯

   创作不易,多多支持!

 在编程的过程中,我们经常要处理字符以及字符串,为了方便操作这些字符和字符串,C语言标准库中提供了一系列库函数,接下来我们就一起来学习这些函数,帮助字符和字符串完成它们的舞会之梦。

目录

一、字符分类函数

二、字符转换函数

三、strlen函数的使用以及模拟实现

方法1

方法2

方法3

四、strcpy函数的使用以及模拟实现

五、strcat函数的使用以及模拟实现

六、strcmp函数的使用以及模拟实现


一、字符分类函数

在C语言中,有一系列函数是专门用来做字符分类的,也就是一个字符是属于什么类型的字符。这些函数都包含在一个头文件:<ctype.h>。

其实上述的函数的使用方法都是非常类似的,所以我们就仅拿其中一个来举例说明。

int islower(int c);

islower函数可以判断一个字符是不是小写字母。

通过返回值来说明是否为小写字母,如果是则返回非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;
		putchar(c);
		i++;
	}
	return 0;
}

因为'A'的ASCII码值是65,'a'的ASCII码值为97,97-65=32,故转换仅需减32即可。

来看运行结果:

二、字符转换函数

C语言中提供了两个字符转换函数:

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

刚刚的代码我们是将字符-32来完成效果,这回我们有了字符转换函数,就可以之间上函数了。

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

 运行结果是一样的:

三、strlen函数的使用以及模拟实现

我们先来看看strlen函数的原型:

size_t strlen(const char* str);

str我们很熟悉了,是string(字符串)的缩写,len其实是length的意思,所以这个函数大概我就能知道字面意思,它是用来求字符串长度的。

我们知道字符串是以'\0'结尾的,而strlen函数返回的就是在字符串在'\0'之前出现的字符的个数(不包含'\0')。

这里要注意几个点:

1.参数指向的字符串必须是以'\0'结尾。

2.参数的返回值是size_t类型的,是无符号的(易错)。

3.strlen函数是需要头文件的,它的头文件是<string.h>。

那了解完strlen的基本知识,接下来我们来看看它的实战使用:

#include <stdio.h>
#include <string.h>
int main()
{
	const char* str1 = "abcdef";
	const char* str2 = "bbb";
	if (strlen(str2) - strlen(str1) > 0)
	{
		printf("str2>str1\n");
	}
	else
	{
		printf("srt1>str2\n");
	}
	return 0;
}

接下来看模拟实现:

方法1

//计数器⽅式
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

法1创建了个临时变量来计数,还使用了指针运算,由于'\0'为假,指针指到它时,也就意味着字符串结束,循环也就结束。我们还用到了assert断言,严谨一些,养成良好的习惯。

方法2

//不能创建临时变量计数器
int my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

法2中我们使用了递归,由于每次我们都是+1,所以很容易想到使用递归来完成代码的实现。这里不会递归的兄弟们,传送门放在下面了:

C语言中的套娃——函数递归_俄罗斯套娃可以用递归实现吗-CSDN博客

方法3

//指针-指针的⽅式
int my_strlen(char* s)
{
	assert(s);
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}

 这种方法也使用了指针运算,可见指针运算有多好用:

灵魂指针,教给(一)-CSDN博客

这篇文章详细地讲述了指针的运算。

首先由于传进来的是字符串的首元素地址,然后我们再创建一个指针来移动,最后指针指向字符串末尾,首尾相减,便能知晓中间长度,也就是字符串的长度。

四、strcpy函数的使用以及模拟实现

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

首先我们认识两个单词:destination n.目的地,source n.源头。

然后我们再来拆分一下strcpy的字面意思,str还是字符串,cpy其实是copy的意思,那我们可以知道了,strcpy是用来拷贝字符串的。

这里说明几点细节:

1.原理:将 source 指向的 C 字符串复制到destination指向的数组中,包括终止 null 字符(并在该点停止)

2.源字符串必须以'\0'结尾。

3.目标空间必须足够大,确保能放下源字符串。

4.目标空间必须是可修改的。

接下来我们来看它的使用:

#include <stdio.h>
#include <string.h>
int main()
{
	char src[40];
	char dest[40];
	strcpy(src, "Hello World");
	strcpy(dest, src);
	printf("最终的目标字符串:%s\n", dest);
	return 0;
}

 来看运行结果:

接下来我们来学习strcpy的模拟实现:

我们可以用两个指针分别指向目的地和源头,然后通过赋值即可完成拷贝。

//1.参数顺序
//2.函数的功能,停⽌条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分
#include <stdio.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	
	while (*src != '\0')
	 {
		*dest = *src;
		dest++;
		src++;
	 }
	*dest = *src; //拷贝'\0'
	return ret;
 }

 上述代码已经可以完成效果了,但是我们还可以有更巧妙的代码:

#include<stdio.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	
	while ((*dest++ = *src++))
	 {
		;
	 }
	return ret;
 }

虽然++的优先级比*高,但是是后置++,先操作后++,所以先解引用,完成赋值后再++,最后到'\0',退出循环,是不是很巧妙。

五、strcat函数的使用以及模拟实现

char *strcat(char *dest, const char *src)

老规矩还是字面分析,str字符串,这个cat可不是小猫的那个cat,而是catenate的缩写,意思是连成一串。

1.原理:将源字符串的副本追加到目标字符串。终止 null 字符在 destination 中被 source 的第一个字符覆盖,并包含一个 null 字符在由两者在目的地的串联形成的新字符串的末尾。

2.源字符串必须以'\0'结尾。

3.目标字符串也需要有'\0',否则不知道从哪开始追加。

4.目标空间足够大。

5.目标空间可修改。

#include <stdio.h>
#include <string.h>
int main()
{
	char src[50];
	char dest[50];
	strcpy(src, "World");
	strcpy(dest, "Hello ");
	strcat(dest, src);
	printf("最终的目标字符串:%s", dest);
	return 0;
}

 运行结果:

之后我们学习strcat的模拟,这个其实很简单,刚刚我们学到了strcpy的模拟,那这个无非就是先找到destination中的'\0'再copy,代码如下:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}

六、strcmp函数的使用以及模拟实现

int strcmp(const char *str1, const char *str2)

cmp是compare的缩写,是比较,顾名思义strcmp是比较字符串的。

1.原理:此函数开始比较每个字符串的第一个字符。如果它们等于彼此,它继续往下比较,直到字符不同或终止达到 null-character。

2.返回值:

  • 如果返回值小于 0,则表示 str1 小于 str2。
  • 如果返回值大于 0,则表示 str1 大于 str2。
  • 如果返回值等于 0,则表示 str1 等于 str2。 

3.比较的是两个字符的ASCII码值的大小。

#include <stdio.h>
#include <string.h>
 
int main ()
{
   char str1[15];
   char str2[15];
   int ret;
 
 
   strcpy(str1, "abcdef");
   strcpy(str2, "ABCDEF");
 
   ret = strcmp(str1, str2);
 
   if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
      printf("str1 大于 str2");
   }
   else 
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}

 strcmp的模拟实现,这个其实很简单,直接上代码:

int my_strcmp(const char* str1, const char* str2)
{
	int ret = 0;
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

未完待续...... 

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

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

相关文章

PyTorch 深度学习(GPT 重译)(一)

第一部分&#xff1a;PyTorch 核心 欢迎来到本书的第一部分。在这里&#xff0c;我们将与 PyTorch 迈出第一步&#xff0c;获得理解其结构和解决 PyTorch 项目机制所需的基本技能。 在第一章中&#xff0c;我们将首次接触 PyTorch&#xff0c;了解它是什么&#xff0c;解决了…

Amuse .NET application for stable diffusion

Amuse github地址&#xff1a;https://github.com/tianleiwu/Amuse .NET application for stable diffusion, Leveraging OnnxStack, Amuse seamlessly integrates many StableDiffusion capabilities all within the .NET eco-system Welcome to Amuse! Amuse is a profes…

跨越时空的纽带:探索Facebook如何连接人与人

引言 Facebook作为全球最大的社交媒体平台之一&#xff0c;已经成为了人们日常生活中不可或缺的一部分。它不仅仅是一个社交网络&#xff0c;更是连接人与人、人与世界的纽带。在这篇文章中&#xff0c;我们将深入探讨Facebook如何跨越时空&#xff0c;连接人与人之间的关系&a…

机器学习-06-回归算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中回归算法&#xff0c;包括线性回归&#xff0c;岭回归&#xff0c;逻辑回归等部分。 参考 fit_transform,fit,transform区别和作用详解&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&am…

spring boot学习第十四篇:使用AOP编程

一、基本介绍 1&#xff0c;什么是 AOP &#xff08;1&#xff09;AOP 为 Aspect Oriented Programming 的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 &#xff08;2&#xff09;利用 AOP…

Cronos zkEVM 基于 Covalent 数据可用性 API,推动其 Layer2 DeFi 生态更好地发展

在一项旨在显著改善 DeFi 生态的战略举措中&#xff0c;Cronos 与 Covalent Network&#xff08;CQT&#xff09;携手合作&#xff0c;以期待 Cronos zkEVM 的推出。这一整合&#xff0c;预计将进一步降低以太坊生态系统的交易成本、提升交易速度&#xff0c;并带来更好的交易体…

ES的集群节点发现故障排除指南(1)

本文是ES官方文档关于集群节点发现与互联互通的问题排查指南内容。 集群节点发现是首要任务 集群互连&#xff0c;重中之重&#xff01; 在大多数情况下&#xff0c;发现和选举过程会迅速完成&#xff0c;并且主节点会长时间保持当选状态。 如果集群没有稳定的主节点&#xf…

四、Elasticsearch 进阶

自定义目录 4.1 核心概念4.1.1 索引&#xff08;Index&#xff09;4.1.2 类型&#xff08;Type&#xff09;4.1.3 文档&#xff08;Document&#xff09;4.1.3 字段&#xff08;Field&#xff09;4.1.5 映射&#xff08;Mapping&#xff09;4.1.6 分片&#xff08;Shards&#…

C语言指针与地址基础学习(取地址运算)

C语言指针与地址基础学习&#xff08;取地址运算&#xff09; 取地址运算&#xff1a;&运算符取得变量的地址代码示例一运算符& 取地址运算&#xff1a;&运算符取得变量的地址 代码示例一 #include<stdio.h> int main() {int a;a 6;printf("sizeof(i…

区块链革命:探索 Web3 的全球影响

引言 自比特币的诞生以来&#xff0c;区块链技术已经成为全球范围内备受瞩目的创新之一。其去中心化、不可篡改、透明的特性不仅使其成为数字货币领域的核心技术&#xff0c;还在金融、供应链管理、智能合约等领域展现出了巨大的应用潜力。随着区块链技术的不断发展&#xff0…

Jackson 2.x 系列【3】解析器 JsonParser

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 前言2. 解析原理3. 案例演示3.1 创建 JsonParser3.2 解析3.3 读取3.4 测试 1. 前…

【Qt】使用Qt实现Web服务器(三):QtWebApp中HttpRequest和HttpResponse

1、HttpRequest 1.1 示例 1)在Demo1的Dump HTTP request示例 在浏览器中输入http://127.0.0.1:8080点击Dump HTTP request 2)切换到页面:http://127.0.0.1:8080/dump 该页面显示请求和响应的内容: Request: Method: GET Path: /dump Version: HTTP/1.1 Headers: accep…

【C语言】【牛客】BC136 KiKi判断上三角矩阵

文章目录 题目 BC136 KiKi判断上三角矩阵思路代码呈现 题目 BC136 KiKi判断上三角矩阵 链接: link 思路 这题很简单但是再牛客中属于中等题 我们通过读题发现 2<n<10 &#xff0c;所以我们首先创建一个变量 n 以及一个 10*10 个元素数组 然后题目是判断该矩阵是否是…

Android 系统开发工具大全

写给应用开发的 Android Framework 教程——玩转AOSP篇之 Android 系统开发工具推荐 下面推荐的是我常用的工具&#xff0c;如果你有好用的开发工具欢迎在评论区留言讨论交流。 1. SSH 服务与 Tabby Terminal SSH 服务使得我们在其他平台上通过 SSH 客户端程序即可访问到我们…

时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测

时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现BiTCN…

Monaco Editor系列(一)启动项目与入门示例解析

前言&#xff1a;作为一名程序员&#xff0c;我们工作中的每一天都在与代码编辑器打交道&#xff0c;相信各位前端程序员对 VS Code 一定都不陌生&#xff0c;VS Code 可以为我们提供代码高亮、代码对比等等功能&#xff0c;让我们在开发的时候&#xff0c;不需要对着暗淡无光的…

Redis模拟小例子

我们模拟游戏中的一个角色&#xff0c;这个角色被动技能就是受到攻击的时候&#xff0c;会有十分之三的概率爆出金币&#xff0c;而在一个回合之中&#xff0c;爆出的金币个数有限制&#xff0c;限制为两个&#xff0c;假设攻击是按照一定的频率进行的&#xff0c;而一个回合的…

海外云手机如何帮助亚马逊引流?

随着全球化的推进&#xff0c;出海企业和B2B外贸企业越来越注重海外市场的开拓&#xff0c;这已成为企业争夺市场份额的重要策略。本文将重点探讨海外云手机在优化亚马逊店铺引流方面的作用和优势。 海外云手机是一种在云端运行的虚拟手机&#xff0c;能够在单一芯片上多开几个…

20---复位电路设计

视频链接 复位电路设计01_哔哩哔哩_bilibili 复位电路设计 1、复位介绍 复位电路又叫初始化电路&#xff0c;它的作用是将芯片的工作状态回到初始状态&#xff01; 复位电路在硬件设计中至关重要&#xff0c;在实际调试的过程中&#xff0c;与复位相关的点必核查&#xff…

极路由4获取不到local_token和uuid的解决方案

今天淘了个二手极路由4(HC5962)&#xff0c;想刷个Openwrt系统来着&#xff0c;就按着网上的教程来进行。 打开极路由ROOT local-ssh利用工具 (hiwifi.wtf)这个网站&#xff0c;然后第一步获取local_token就出问题了&#xff0c;显示的字是"找不到文件..."&#xff…