字符函数和字符串函数(C语言)

news2024/9/23 17:25:45

目录

一. 字符分类函数

二. 字符转换函数

三.多种函数的使用和模拟实现

3.1 strlen函数

3.2 strcpy函数

3.3 strcat函数

3.4 strcmp函数

3.5 strncpy      strncat      strncmp 


🍟🧣结束了指针的学习,我们开始了字符串之旅,今天我们要学习的的是与字符相关的函数,在编程的过程中,我们经常要处理字符和字符串,为了方便操作字符和字符串,C语言标准库中提供了一系列库函数,接下来我们就学习一下这些函数。

一. 字符分类函数

什么是字符分类函数?

C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。
这些函数的使用 都需要包含一个头文件是#include <ctype.h>。 比如islower函数,它就是判断字符的大小写,如果是小写字符就返回非零数字,大写就返回0。我们来一段代码试写一下:
#include <ctype.h>
int main()
{
	char arr[20] = { "helloword" };
	int ret = printf("%d\n", islower(arr[3]));
	return 0;
}

如上图所示,我们将返回值传给一个整型变量的值,直接使用函数进行计算,我们通过返回值是否为0来判断传入的字符是哪种类型,大家下去可以自己多去尝试。另外除了islower函数我们还有一些其他的分类函数,如下图: 

这是一些比较常见的字符分类函数,还有其他的的一些函数,我们可以去相关的网站上查询,我们如果用到这些函数,也要多加练习。 

二. 字符转换函数

C语言中有2个转换函数:

1. int tolower ( int c ); // 将参数传进去的大写字母转小写
2. int toupper ( int c ); // 将参数传进去的小写字母转大写
#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;
}

三.多种函数的使用和模拟实现

3.1 strlen函数

我们先来学习第一个函数strlen函数,这个函数我们在之前也讲到过,strlen函数是计算字符串在/0之前的字符个数,使用方法我们也是知道的,就不再过多演示,那到底要怎样实现这个函数呢?,现在我们来模拟实现一下:

//strlen函数的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
//计数器方式
size_t my_strlen(const char* arr)
{
		int count = 0;
		assert(arr);
		while (*arr)
		{
			count++;
			arr++;
		}
		return count;
	
}
//不能创建临时变量计数器
size_t my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}
//指针-指针的⽅式
int my_strlen(char* s)
{
	assert(s);
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	char arr[20] = "helloward";
	size_t ret = my_strlen(arr);
	printf("%zd\n", ret);
	return 0;
}

从上图的代码我们可以知道,strlen函数的模拟实现有三种方法,第一种是最常见的计数法,创建一个计数变量count,跟随着指针的移动开始计数,当指针指向'/0'的时候结束计数,也刚好返回我们所要的字符个数。而第二种方法其实有点类似于我们的递归思想,我们不断的调用my_strlen这个函数,并且让指针不断的向后移动直到找到'/0',累积相加的结果就是我们所要找的字符个数。第三种方法是指针-指针的方法,我们之前也有了解过,指针的相减计算的是两个指针之间的字符个数,所以我们可以使用指针-指针的方法来实现。

3.2 strcpy函数

strcpy函数是干什么呢?它的作用就是复制一个字符的内容到所需要的地方去,它是C语言中的一个库函数,所以所需要的头文件是<string.h>,strcpy函数的原型是:char*strcpy(char*destination,const char* source),那么他的要求是什么呢?首先我们要知道源字符串中是必须有'/0'的,如果没有就没有复制结束的标志,同时目标空间要足够大,能够放得下我们要复制的东西,并且我们的目标空间是可以修改的,这个时候我们就注意到在我们的函数原型中destination前面是没有const修饰的。另外strcpy返回的是目标空间的起始地址。

int main()
{
	char arr1[20] = { 0 };
	char* p= "world";;
    strcpy(arr1, p);
	printf("%s\n", arr1);
	return 0;
}

🧀🧀那我们要怎么模拟实现这个函数呢?其这个并不是很难的,我们知道两个数组的地址,以及它们首元素的指针,并让他们相等,我们来模拟实现一下:

#include <assert.h>
char* my_strcpy(char* d, const char* s)
{
	char* ret = d;
	assert(d!= NULL);
	assert(s != NULL);
	while (*d++ = *s++)
	{

	}
	return ret;
	
}

int main()
{
	char arr1[20] = { 0 };
	char* p= "world";;
    my_strcpy(arr1, p);
	printf("%s\n", arr1);
	return 0;
}

3.3 strcat函数

🎡接下来认识一下strcat函数,这个函数是干什么呢?它的作用是字符串追加,就是将一个字符串追加到另一个字符串的后面。它的原型就是char* strcat(char* destiantion,const char* source)对于strcat函数,两个空间必须都有'/0'结尾,而且尽量不要自己对自己进行追加,容易引发错误,并不保证完全成功。现在我们来使用一下这个函数:

#include <string.h>
int main()
{
	char arr1[20] = { "abcdef" };
	char arr2[20] = { "abc" };
	strcat(arr1 + 5, arr2);
	printf("%s\n", arr1);
	return 0;
}

输出的结果就是abcdefabc。就是将arr2追加到arr1的后面去。我们要如何模拟这个函数的实现呢?

//模拟实现
#include <assert.h>
char* my_strcat(char* d, char* s)
{
	char* ret = d;
	assert(d != NULL);
	assert(s != NULL);
	while (*d)
	{
		d++;
	}
	while ((*d++ = *s++))
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = { "abcdef" };
	char arr2[20] = { "abc" };
	my_strcat(arr1 + 5, arr2);
	printf("%s\n", arr1);
	return 0;
}

通过上面的代码,我们可以看到,首先目标字符串和源字符串都不能是空指针,另外就是我们先使用whlie循环将d++进而找到正确的位置进行字符串的追加,之后再使用*d++=*s++,让源字符串正确追加到目标字符串的后面,最后返回我们设定好的ret。但是又有一个问题出现了,就是能不能用这个函数进行自己的追加呢?我们来试一下:

#include <assert.h>
char* my_strcat(char* d, char* s)
{
	char* ret = d;
	assert(d != NULL);
	assert(s != NULL);
	while (*d)
	{
		d++;
	}
	while ((*d++ = *s++))
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = { "abcdef" };
	my_strcat(arr1 + 5, arr1);
	printf("%s\n", arr1);
	return 0;
}

我们会发现程序根本不会运行出来任何东西,这就说明这个函数不适合自己给自己追加,我们可以使用strncat函数来进行追加,具体是为什么呢?

3.4 strcmp函数

🧣strcmp函数有什么作用呢?顾名思义,strcmp函数是专门进行字符串比较的,它的原型是int strcmp(const char*str1,const char*str2),字符串进行比较是对应着比较,并不是比较长度,是比较它们对应的AASCII码值。当str1>str2的时候,返回小于0的数字;当str1>str2的时候,返回大于0的数字;当str1=str2的时候返回0。

#include <string.h>
int main()
{
	char arr1[20] = { "abcdef" };
	char arr2[20] = { "abch" };
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

 

返回-1就说明了str1小于str2,那么现在我们看来模拟一下strcmp函数是怎样模拟实现的:

#include <assert.h>
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;
}
int main()
{
	char arr1[20] = { "abcdef" };
	char arr2[20] = { "abch" };
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

 

3.5 strncpy  strnca  strncmp 

看到这三个函数大家一定会觉得很眼熟,确实,那么这三个函数的用法以及含义是什么呢?我们先来说strncpy函数的原型char* strncpy(char* dest,const char*sour,size_t num),很容易看出来它的参数比strcpy多了一个参数size_t num,其他的三个函数都是一样的,参数都多了一个size_t num,它们用于长度受限制的函数,对于strncpy函数来说,就是将源字符串中的前num个字符复制到目标字符串中去,如果源字符串的长度小于num,则拷贝完源字符串之后在后面追加0,直到num个同时对于strncmp函数来说,因为有个数限制,所以strncat来说就可以实现自己对自己的追加,并且在追加之后有/0的存在,表示停止

eg:

#include <stdio.h>
#include <string.h>
int main()
{
	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	strncat(str1, str2, 6);
	printf("%s\n", str1);
	return 0;
}

 

 如上面的代码我们就是将str2中的前6个字符追加到字符串str1中去。

同样对于strncmp函数来说,它的原型是 int strncmp ( const char * str1, const char * str2, size_t num );
比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0.

      

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

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

相关文章

【若依项目-RuoYi】掌握若依前端的基本流程

搞毕设项目&#xff0c;使用前后端分离技术&#xff0c;后端springBoot&#xff0c;前端vue3element plus。自己已经写好前端与后端代码&#xff0c;但想换一个前端界面所以使用到了若依&#xff0c;前前后后遇到许多坑&#xff0c;记录一下&#xff0c;方便之后能够快速回忆。…

创意指南丨VR游览沉浸式空间体验

欢迎来到我们制作的VR幻想世界。玩家的起点是一条蓝色水晶大道&#xff0c;让我们一起探索这个如梦似幻的境地。 在这条大道的两侧&#xff0c;漂浮着半透明的大水晶水母。它们轻盈地在空中飘动&#xff0c;仿佛在欢迎我们的到来。这条道路上方&#xff0c;一个个半圆环不停地…

人脸身份证比对接口如何用Java对接?(二)

一、什么是人脸身份证比对&#xff1f; 人脸身份证比对又称人证比对&#xff0c;实人比对&#xff0c;人像比对&#xff0c;输入姓名、身份证号码和头像照片&#xff0c;与公安库身份证头像进行权威比对&#xff0c;返回分值作为判断依据。 二、人脸身份证比对接口适用哪些场…

iMovie Tutorial【iMovie 剪辑教程】

文章目录 项目字幕视频截取范围 显示进度条大小播放速度视频图层降噪转场设置转场时间 声音录制声音 分享导出文件 项目 字幕 视频 截取范围 i、o、e 显示进度条大小 播放速度 视频图层 例如&#xff1a;视频衔接、插入表情视频、头像对话 降噪 户外录制视频需要降噪。…

计算机学习

不要只盯着计算机语言学习&#xff0c;你现在已经学习了C语言和Java&#xff0c;暑假又规划学习Python&#xff0c;最后你掌握的就是计算机语言包而已。 2. 建议你找一门想要深挖的语言&#xff0c;沿着这个方向继续往后学习知识就行。计算机语言是学不完的&#xff0c;而未来就…

在ccs theia上用jlink下载烧录调试msp芯片配置

转载自ti官网的文章结合我自己的经历 将 Segger 编程器与 MSPM0 配合使用 1. 引言 本指南说明了如何将 Segger 编程器与 MSPM0 配合使用。 本文档不用于详细说明如何使用 Segger 工具。有关详细文档&#xff0c;请参阅相应的 IDE 或 Segger 文档。 2. 先决条件 用户应已下…

某个国外的真实XSS漏洞利用探寻

Background 在一次测试中&#xff0c;在git中找到部分的源码&#xff0c;发现可能存在xss问题&#xff0c;但是经过了一点处理&#xff0c;于是经过探寻思考&#xff0c;找到了bypass的方法&#xff0c;写下本篇文章 Part.1 从git到混淆 server头看见这个配置 基本是flask了,…

普中51单片机:DS18B20温度传感器操作指南(十三)

文章目录 引言电路图引脚讲解初始化时序写时序读时序温度变换温度读取完整代码 引言 DS18B20是一款单总线接口的数字温度传感器&#xff0c;仅需一个IO口即可实现数据通信。这里只对如何简单操作开发板的DS1802进行讲解&#xff0c;关于DS18B20温度传感器的详细操作原理&#…

矢量文件坐标转换:2000坐标系转换为wgs84坐标系,具体代码实现

最近在处理矢量样本的时候&#xff0c;遇到一些shp文件的坐标系为2000坐标&#xff0c;需要统一地把非WGS84坐标系的矢量转换为WGS84坐标系。 本文记录一下如何进行2000坐标系转化为wgs84坐标系的过程。 在处理矢量数据转换的过程中&#xff0c;有几个关键步骤确保了数据的有效…

ComfyUI LoRA应用和三级放大

ComfyUI LoRA应用和三级放大 LoRA加载器LoRA应用三级放大 LoRA加载器 新建节点–>加载器–>LoRA加载器 LoRA应用 如下图串起来 三级放大

ActiveMQ任意文件写入漏洞(CVE-2016-3088)复现

一.环境配置 腾讯云的ubuntu操作系统&#xff0c;已经安装有docker 和 vulhub 直接来到 启动环境docker-compose&#xff0c;要在root权限下运行。 docker-compose up -d 若出现等待时间过长的情况&#xff0c;请参考这篇文章http://t.csdnimg.cn/SYhbE 访问http://公网ip:8…

Vivado启用modelsim报错boost::filesystem::remove

问题描述 在vivado中以配置好仿真工具为modelsim&#xff0c;但是启动仿真时报错如下&#xff1a; boost::filesystem::remove: 另一个程序正在使用此文件&#xff0c;进程无法访问。 "C:/Users/ZYP_PC/Desktop/verilog_test/simulation_project/project_1/project_1.si…

VTK8.2.0编译(Qt 5.14.2+VS2017)

VTK8.2.0编译(Qt 5.14.2+VS2017) 关于Qt和MSVC的安装,可以参考文章(Qt+MSVC2017)。 本篇VTK在Qt+MSVC的配置下的编译。VTK 以8.2.0为例。 一、环境变量的配置 我们打开电脑的环境变量,可以看到没有Qt相关的路径的配置: 我们把Qt相关的变量增加一下(主要以64位为主,…

day02-员工管理、Swapper测试、JWT、ThreadLocal、全局时间转换

苍穹外卖-day02 课程内容 新增员工员工分页查询启用禁用员工账号编辑员工导入分类模块功能代码 **功能实现&#xff1a;**员工管理、菜品分类管理。 员工管理效果&#xff1a; 菜品分类管理效果&#xff1a; 1. 新增员工 1.1 需求分析和设计 1.1.1 产品原型 一般在做需求…

LNMP环境搭建论坛

注意&#xff1a;这里用的是Rocky Linux自带的Nginx 1.1 环境准备 1.1.1 安装部署Nginx、MySQL和PHP相关组件 [rootRocky8-node1 ~]# yum install nginx php-mysqlnd php php-gd php-fpm php-xml mysql-server -y 1.1.2 启动服务 [rootRocky8-node1 ~]# systemctl enable …

【C++】C++入门基础【类与对象】

目录 1.类 1.1类的定义 1.2struct 与 class对比 2.访问限定符 3. 类域 4.实例化 5.存储大小----内存对齐 6.this指针 1.类 1.1类的定义 class作为类的关键字&#xff0c;后面跟的是类的名字&#xff0c;如Stack&#xff0c;{}中的为类的主体&#xff0c;类定义结束时…

cpp笔记07:STL

STL 基本概念 STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09; STL从广义上分为&#xff1a;容器&#xff08;container&#xff09;算法&#xff08;algorithm&#xff09;迭代器&#xff08;iterator&#xff09; 容器和算法之间通过迭代器…

8.7 Day15 匿名用户访问FTP与日志查看

查看配置文件 vsftpd是一个认证文件&#xff0c;意味着ftp是通过vsftpd这个认证文件来对我们输入的用户名和密码进行认证的&#xff0c;那么这个认证文件在哪里呢&#xff1f; 所在位置如下&#xff1a; 查看文件配置内容 默认通过系统来验证&#xff0c;但现在我们欲做一个类…

web自动化7-pytest④实践测试用例-回归用例web自动化部分代码

文档说明: 本文档包括web自动化目录结构代码元素定位 : 父级, 同级后面, 同级div, 包含, 不包含, 鼠标右键, 悬停, 句柄切换(浏览器切换,关闭), 不可见元素查找, 滑动到不可见元素出现, 悬停后点击, 页面有值判断, 页面数据量判断web自动化: 前置, 后置事件 结合上篇文章, 基本…

Django—模板继承和包含

模块的继承意义&#xff1a;将需要多次用到的内容&#xff08;盒子&#xff09;进行引用&#xff0c;减少代码的重复使用 如我们经常在网上看见的导航栏&#xff0c;页脚等 第一步&#xff1a;我们将继承模块写在一个html文件里面 第二步&#xff1a;创建一个html文件&#x…