C语言进阶指南(14)(部分字符串库函数及其模拟实现)

news2024/11/25 7:28:16

欢迎来到博主的专栏——C语言进阶指南
博主id:reverie_ly

文章目录

    • 1、strlen()——字符串长度计算函数
      • 自定义strlen函数的实现
    • 2、strcpy——字符串拷贝函数
      • strcpy的模拟实现
    • 3.strcat——字符串追加函数
      • strcat的模拟实现
    • 4、strcmp——字符串比较函数
      • strcmp的模拟实现
    • 加了限定条件的字符串操作函数
    • 更多的库函数

C语言标准定义了一系列有关字符串操作的函数,编译器会根据标准中的定义实现这些函数, 并将这些字符串函数定义在头文件<string.h>中
如果想要使用这些字符串函数,需要在包含这个头文件

#include<string.h>

1、strlen()——字符串长度计算函数

在这里插入图片描述

该函数的计算方式是从传进函数的地址值的第一个元素开始,直到结束标志‘\0’之间的所有元素的长度作为函数的返回值。

字符串必须有结束标志‘\0’,否则返回值将是一个随机值(strlen函数继续在内存中寻找‘\0’,返回值是从目标地址到‘\0’的元素长度)。

函数的返回值是size_t.由定义可知,size_t类型实质上是unsigned int类型。

在这里插入图片描述
以字符串“hello,world”为例。

char ch[12] = { "hello,world" };

如果将首元素的地址传入strlen函数,返回值是从‘h’—‘\0’之间的元素个数,(不计入‘\0’)

strlen(ch);//返回值为11

在这里插入图片描述
也可以传递字符串的其他元素,此时函数的返回值是以传入的元素为起始,一直到‘\0’之间的字符个数

strlen(&ch[4]);//将字符串中的第五个元素的地址传入函数中

在这里插入图片描述
此时strlen函数的返回值为7

自定义strlen函数的实现

前面已经知道了strlen函数的原理
(1)函数原型的参数是字符串的地址
(2)函数的返回值是size_t类型(size_t定义在<stdio.h>中)
(3)函数从传入的地址为起始位置,一直计算到’\0’之间的字符个数

我们可以根据(1)(2)设计出函数原型

#include<stdio.h>
size_t my_Strlen(const char*str);

为了实现(3),我们将指针从起始位置逐个解引用,判断是否为‘\0’,不是‘\0’就给计数增加1.

size_t my_strlen(const char* pstr)
{
	size_t count = 0;
	while (*pstr != 0) 
	{
		count++;
		pstr++;
	}
	return count;
}

润色一下可以变成

size_t my_strlen(const char* pstr)
{
	size_t count = 0;
	while (*pstr++&&++count);//这里是利用了&&的的特性,如果大家感兴趣
	//可以去看看博主那篇关于逻辑运算符的文章哦~
	return count;
}

2、strcpy——字符串拷贝函数

在这里插入图片描述
将source地址的字符串(从开始地址到结束标志)拷贝到destination字符串中去。
1)目的字符串必须能被修改。
2)目的字符串的容量需要大于原字符串。
3)原字符串需要有结束标志‘\0’

char str1[20]="reverie";
char str2[20]="hello";
strcpy(str1,str2);

strcpy会将str2中的字符串(从首元素到‘\0’之间的所有字符,包括‘\0’)拷贝到str1中。
在这里插入图片描述

strcpy的模拟实现

返回类型是目的字符串的地址,参数是两个字符型指针,源字符串不更改,使用const固定变量。

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

一直到打印完源字符串(从起始地址到结束标志)

实现这个功能可以将source指向的元素传到destination指针指向的元素中,接着两个指针继续拷贝后边的字符,直到source拷贝完‘\0’

char* my_strcpy(char* destination, char* source)
{
	char* ret = destination;//保存起始地址
	while (source != '\0')
	{
		*destination = *source;
		destination++;
		source++;
	}
	*destnation=*source;
	return ret;//拷贝完成后返回起始地址
}

跳出循环后需要加上一句*destination=*source,这是因为循环结束的条件是*source!=‘\0’(如果不限定的话会死循环),但是根据上面实现的结果来看,source字符串的第一个’\0’是要被读入进去的,所以在循环结束后需要加上*destination=*source;
(而且字符串是一个从起始字符一直到第一个字符串结束符号‘\0’组成的字符集合,不录入\0是不能算作拷贝一个字符串的)

稍微润色一下变成

char* my_strcpy(char* destination, char* source)
{
	char* ret = destination;
	while (*source++ = *source++);
	return ret;
}

3.strcat——字符串追加函数

在这里插入图片描述

将source字符串的所有字符追加到destination字符串,具体实现是将source字符串的首元素开始依次附加到destination字符串的第一个结束标志‘\0’。返回值为追加后的destination字符串的地址

char str1[12]="hello";
char str2[]=",world";
strcat(str1,str2);

在这里插入图片描述

1)目标字符串的空间需要足够大(能够容纳追加后的字符个数)
2)源字符串需要有结束标志
3)源字符串不能被修改(所以不能自己追加自己)。
4)目标字符串能被修改

strcat的模拟实现

(1)源字符串不能被修改,用const修饰指针。
(2)函数的返回值是指向目的字符串的指针。
(3)将原字符串追加到目的字符串。从目的字符串的第一个字符串结束标志开始追加

由(1)(2)可以得出strcat的函数原型

char* my_strcat(char*destnation,const char*source);

实现(3)的方法是:
先将指针指向目的字符串的第一个字符串结束标志处。
将源字符串的元素依次拷贝到目的字符串的指针处的元素。

char* my_strcat(char* destination, const char* source)
{
	char* ret = destination;
	while (*destination != '\0')
		destination++;
	while (*source != '\0')
	{
		*destination = *source;
		destination++;
		source++;
	} 
	*destination=*source;
	return ret;
}

稍微润色一下变成

char* my_strcat(char* destination, const char* source)
{
	char* ret = destination;
	while (*destination)
		destination++;
	while (*destination++ = *source++);
	return ret;
}

4、strcmp——字符串比较函数

在这里插入图片描述

将字符串中的每个字符依次对比大小(ASCII码值),若大于则返回1,小于则返回-1,若相同,则继续对比双方字符串下一个元素,直到某一方出现不同的值或出现字符串结束标志‘\0’,若自始至终对比的双方字符串中的每一个元素都相等,则返回值为0.

不同的编程环境下返回值的结果不同,在vs中返回值为1,0,-1,而gcc中返回值为判定元素(被比较的字符)之间ASCII码值的差值。

在这里插入图片描述

以上例为例,str1与str2进行字符串比较时,‘w’与‘w’相等,继续比较下一个。‘o’与‘o’相等,继续比较下一个。‘r’与‘r’相等,继续比较下一个。‘l’与‘d’比较,不相等,由于‘l’的ASCII码值比‘d’大,函数的返回值大于0.

在这里插入图片描述

‘w’和‘w’相等,比较下一个,以此类推,当某一个字符串比较到‘\0’时,停止比较,此时判断双方对应比较的字符是否都是‘\0’,如果一致,则判断这两个字符串相等。

strcmp的模拟实现

(1)函数的返回值是有符号型(有负数,有正数)
(2)对比过程中不对字符串的数据进行修改,可以用const修饰函数参数。
(3)将字符串的元素依次比较大小,满足上面的规则
根据(1)(2),可以确定函数原型

char* my_strcmp(const char*str1,const char*str2)
{
char* my_strcmp(const char* str1, const char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
		return 0;
}
}

如果想要模拟的是gcc编译器的strcmp实现效果的话,模拟实现应该是。

char* my_strcmp(const char* str1, const char* str2)
{
	while (*str1 == *str2)
	{
		if (!str1)
			return 0;
		str1++, str2++;
	}
	return *str1 - *str2;
}

加了限定条件的字符串操作函数

strcpy,strcmp,strcat的限定条件都是字符串结束标志‘\0’。为了达到更灵活的效果(比如只拷贝字符串的前几个字符,而不用一直拷贝到‘\0’)。C语言推出了加了限定条件的字符串操作函数:strncpy,strncmp,strncat。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
依次对比strcpy,strcat,strcmp的声明我们发现其多出一个size_t的参数count。这是用来计算参与函数的字符串中的限定元素个数。
在这里插入图片描述

由strncpy的模拟实现我们可以知道syrncpy的特点是1)将源字符串的前n个字符传递到目的字符串,若原字符串的字符数小于n,则其余字符(n-已修改字符)改为‘\0。

在这里插入图片描述

strcmp一直对比到某一方出现‘\0’或不同,strncmp是依次对比前n个字符是否相等。但是当strncmp中的前n个字符串中存在‘\0’也会停止对比。

这些函数无非就是在原有的函数原型上加上了一个限定条件count,这个count是限定了需要参与这个函数的字符的最大个数。

更多的库函数

cplusplus网站,这里有C语言所有库的库函数的讲解

也可以使用msdn软件来查看这些库函数的使用方法以及函数的返回类型。
在这里插入图片描述
(可以私信博主来获取msdn软件哦~)

也可以继续关注博主,博主会带来常用库函数的讲解哦(额)

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

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

相关文章

喜讯!安全狗入选《2024中国企业服务云图(精选版)》多个细分领域

近日&#xff0c;由吴中区人民政府、苏州市工信局指导&#xff0c;崔牛会主办&#xff0c;苏州太湖国家旅游度假区管委会协办的2023中国SaaS大会在苏州顺利举办。 作为国内云原生安全领导厂商&#xff0c;安全狗突出的多项安全能力也在大会上受到认可。 厦门服云信息科技有限公…

软件需求分析报告

《软件需求分析报告》 软件开发全套资料获取&#xff1a;点我获取

VR虚拟教育展厅,为教学领域开启创新之路

线上虚拟展厅是一项全新的展示技术&#xff0c;可以为参展者带来不一样的观展体验。传统的实体展览存在着空间限制、时间限制以及高昂的成本&#xff0c;因此对于教育领域来说&#xff0c;线上虚拟教育展厅的出现&#xff0c;可以对传统教育方式带来改革&#xff0c;凭借强大的…

【RT-DETR改进】SIoU、GIoU、CIoU、DIoU、AlphaIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了RT-DETR的重大改进&#xff0c;特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体&#xff0c;如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU&#xff0c;还融合了“Alpha”思想&#xff0c;创造了一系列新的损失函数。这些组合形式的…

私域数字化建设:解锁企业融资新引擎

私域数字化建设对于增加企业融资能力的机遇是十分重要的&#xff0c;随着数字化经济的快速发展和数据技术的不断进步&#xff0c;企业需要正确认识到数据资产的重要性和私域数字化建设在提升融资能力等方面所带来的机遇。 近期&#xff0c;财政部发布了《企业数据资源相关会计…

教你设置疯狗都咬不烂的防火墙

1 安全技术和防火墙 1.1 安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安全…

一文详解Python中常用数据类型

文章目录 Python 中常用的数据类型包括&#xff1a;Python 中布尔类型(bool)Python 中的数字类型概述Pyhon中的字符串概述Python 中的List概述Python 中的元组类型(tuple)Python中的字典&#xff08;Dictionary&#xff09;Python中的集合&#xff08;Set&#xff09;Python中的…

基于STM32+定时器中断和定时器外部时钟(标准库函数讲解)

前言 本篇博客主要学习了解定时器的标准库函数&#xff0c;以及定时器中断进行LED灯的反转&#xff0c;还有定时器外部时钟获取脉冲计数功能。本篇博客大部分是自己收集和整理&#xff0c;如有侵权请联系我删除。 本篇博客主要是对通用定时器来讲解&#xff0c;功能适中比较常…

C语言进阶指南(15)(函数指针的创建与使用)

*欢迎来到博主的专栏——C语言进阶指南 博主id 文章目录 函数指针函数指针的应用——回调函数函数指针数组 函数指针 函数也有地址&#xff08;函数在调用的时候会占用内存空间&#xff0c;所以函数是有地址的&#xff09;&#xff0c;因此我们也可以用一个指针指向函数 1 函数…

OSCP系列靶场-Esay保姆级

总结 getwebshell : ftp可匿名登录 → 发现隐藏文件夹 → 发现ssh密钥 → 猜解ssh用户名 → ssh密钥登录 提 权 思 路 : 发现suid权限文件 → cpulimit提权 准备工作 启动VPN 获取攻击机IP → 192.168.45.191 启动靶机 获取目标机器IP → 192.168.179.130 信息收集-端口扫…

基于SpringBoot实现的教务查询系统

一、系统架构 前端&#xff1a;html | js | css | jquery | bootstrap 后端&#xff1a;springboot | springdata-jpa 环境&#xff1a;jdk1.7 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 管理员端-课程管理 03. 管理员端-学生管理 04. 管理员端-教师管理…

又有两大巨头官宣加入鸿蒙, 鸿蒙已成, 华为余承东说得没错

自从华为发布HarmonyOS 4系统后&#xff0c;宣布下一个鸿蒙版本将不再支持安卓应用&#xff0c;并启动鸿蒙原生应用&#xff0c;随后国内巨头纷纷响应&#xff0c;为鸿蒙系统开发原生应用。 如今&#xff0c;又有两大巨头官宣加入鸿蒙&#xff0c;一家是广汽传祺&#xff0c;M…

智慧工地解决方案,Spring Cloud智慧工地项目平台源码

智慧工地一体化信息管理平台源码&#xff0c;微服务架构JavaSpring Cloud UniApp MySql 智慧工地云平台是专为建筑施工领域所打造的一体化信息管理平台。通过大数据、云计算、人工智能、物联网和移动互联网等高科技技术手段&#xff0c;将施工区域各系统数据汇总&#xff0c;建…

Flutter创建TabBar

使用TabBar和TabBarView来创建一个包含"首页"、"分类"和"我的"的TabBar。每个Tab对应一个Tab控件&#xff0c;TabBarView中的每个页面对应一个Widget。 1.Tab使用自定义图标和颜色 一般UI设计的图会带渐变色之类的&#xff0c;应该保持图片的原…

由于找不到steam_api64.dll如何修复?steam_api64.dll丢失多种解决方法

steam_api64.dll文件介绍 steam_api64.dll是Steam平台的一个关键组件&#xff0c;主要用于支持Steam客户端和相关游戏的应用程序。这个文件缺失或损坏会导致Steam及相关游戏无法正常运行。它位于Steam安装目录的bin子文件夹中。 steam_api64.dll丢失的原因 系统误删&#xf…

品味丰富美食,羊大师温暖心灵

品味丰富美食&#xff0c;羊大师温暖心灵 冬季来临&#xff0c;寒冷的天气让人们渴望寻找一种温暖和满足感&#xff0c;这时候美食便成了一种心灵享受。冬季与美食的结合&#xff0c;使得人们在寒冷的冬日也能感受到温暖与欢乐。本文小编羊大师将带大家领略冬季与美食的完美结…

C库函数—sprintf

函数介绍&#xff1a; C 库函数 int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。 参数&#xff1a; str -- 这是指向一个字符数组的指针&#xff0c;该数组存储了 C 字符串。format -- 这是字符串&#xff0c;包含了要被写入到字符串 …

网络入门---网络的大致了解

目录标题 网络发展的简单认识协议作用的理解协议的本质什么是协议分层网络通信所面对的问题OSI七层模型TCP/IP模型协议报头的理解局域网通信局域网通信基本原理报头的问题局域网的特点跨网的网络链接如何查看mac地址 网络发展的简单认识 通过之前的学习我们知道计算机是给人提…

九章正式推出『智能驾驶产业数据库』

为了更好地研究产业变化趋势&#xff0c;在定性分析之外增加更多定量分析的内容&#xff0c;从而帮助自动驾驶产业内的朋友们更快速、更精准地把握市场变化&#xff0c;2022年底&#xff0c;九章决定要做智能驾驶产业数据库。 历时将近一年后&#xff0c;从敲定数据库负责人&am…

【古月居《ros入门21讲》学习笔记】10_话题消息的定义与使用

目录 说明&#xff1a; 1. 话题模型 2. 实现过程&#xff08;C&#xff09; 自定义话题消息 Person.msg文件内容 Person.msg文件内容说明 编译配置 在package.xml文件中添加功能包依赖 在CMakeLists.txt中添加编译选项 编译生成语言相关文件 创建发布者代码&#xff…