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

欢迎来到博主的专栏——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;}elsereturn 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.hqwc.cn/news/231880.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】yaml.safe_load()函数详解和示例

在Python中&#xff0c;PyYAML库提供了对YAML&#xff08;YAML Ain’t Markup Language&#xff09;文件的强大支持。YAML是一种直观的数据序列化标准&#xff0c;可以方便地存储和加载配置文件、数据日志等。 yaml.safe_load和yaml.load是Python的PyYAML库提供的两个函数&…

边界突破之linux系统上线Cobalt Strike

别低头&#xff0c;皇冠会掉&#xff1b;别流泪&#xff0c;坏人会笑 基础文件 加载插件 服务端开启监听 windows/beacon_https/reverse_https 类型的beacon 生成木马Beacon 命令如下 linux ./genCrossC2.Linux [TeamServer的IP] [HTTPS监听器端口] [.cobaltstrike.beacon_k…

【洛谷算法题】P5716-月份天数【入门2分支结构】

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5716-月份天数【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格式&a…

(C++)移动零--双指针法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

IDEA如何配置Git 遇到问题的解决

新建项目 点击 会变红 会生成.git隐藏文件 配置远程仓库路径&#xff1a;点击Manage Remotes&#xff1a;将远程仓库的链接放到这里&#xff1a; 得到如下样式&#xff1a; 此时提交到本地仓库 点击add&#xff0c;添加到暂存文件&#xff1a; 此时文件变绿&#xf…

J2EE征程——第一个纯servletCURD

第一个纯servletCURD 前言在此之前 一&#xff0c;概述二、CURD1介绍2查询并列表显示准备实体类country编写 CountryListServlet配置web.xml为web应用导入mysql-jdbc的jar包 3增加准备增加的页面addc.html编写 CAddServlet配置web.xml测试 4删除修改CountryListServlet&#xf…

36.JavaScript补完计划:typescript

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 一、什么是typescript 二、应用场景 我认为JavaScript的特点就是在于它强大的延展性&#xff0c;不仅蔓延到了后端&#xff0c;而且也逐渐成为代码世界无法被忽视的存在。那么&#xff0c;编写js代码时我们都会经常遇到…

【Springboot系列】SpringBoot整合Jpa

文章目录 前言&#xff1a;什么是JPA&#xff1f;JPA优缺点优点1.简化开发&#xff1a;2.高度抽象&#xff1a;3.跨数据库支持&#xff1a;4.自动化的事务管理&#xff1a; 缺点1.学习成本较高&#xff1a;2.性能问题&#xff1a;3.灵活性受限&#xff1a; 示例版本依赖代码Use…

vuepress-----7、发布在GitHub

# 7、发布在GitHub 在你的项目中&#xff0c;创建一个如下的 deploy.sh 文件&#xff08;请自行判断去掉高亮行的注释&#xff09;: #!/usr/bin/env sh# 确保脚本抛出遇到的错误 set -e# 生成静态文件 npm run docs:build# 进入生成的文件夹 cd docs/.vuepress/dist# 如果是发…

7.浮点数转为整数【2023.11.29】

1.问题描述 给出一个浮点数&#xff0c;请将这个浮点数转换成整数。 2.解决思路 输入一个浮点数。 输出程序将浮点数转换为整数并输出。 3.代码实现 numfloat(input("请输入一个浮点数")) num1int(num) print(num1)4.运行结果

RabbitMQ的Web管理页面

访问页面 http://IP:15672/账号密码默认都是&#xff1a;guest 主页概览 Overview 显示当前RabbitMQ Broker的运行信息、连接信息、集群信息以及配置信息等。 连接 Connections 无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#…

【Openstack Train安装】四、MariaDB/RabbitMQ 安装

本章介绍了MariaDB/RabbitMQ的安装步骤&#xff0c;MariaDB/RabbitMQ仅需要在控制节点安装。 在安装MariaDB/RabbitMQ前&#xff0c;请确保您按照以下教程进行了相关配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Opensta…