C语言(字符、字符串函数)2

         Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,欢迎欢迎~~     

                                                💥个人主页:小羊在奋斗

                                                💥所属专栏:C语言   

        本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为一些学友们展示一下我的学习过程及理解。文笔、排版拙劣,望见谅。 

                                6、strcmp 的使用和模拟实现

                                7、strncpy、strncat 和 strncmp

                                8、strtok 的使用和模拟实现

                                9、strstr 的使用和模拟实现

                                10、strerror 函数的使用

6、strcmp 的使用和模拟实现

        6.1 strcmp 的用法

        其实对于 strcmp 函数我们并不陌生,在之前的学习中已经不止一次用到过。

        strcmp 函数的作用是比较两个字符串的大小,当结果是大于时返回一个正值,小于时返回一个负值,等于时返回0。所以 strcmp 函数的返回值是int类型,我们在使用字符串函数的时候一定要清楚每个函数的返回值是什么。

        要特别注意的是,strcmp 函数比较两个字符串比较的不是字符串的长度,而是对应位置字符的ASCII码值。 

      可以看到,当对应位置字符的ASCII码值前者大于后者时,strcmp 函数返回了1;当小于时,strcmp 函数返回了-1;当等于时,strcmp 函数返回了0。来看下面代码示例:

        这个代码有没有什么问题呢?其实,上面的代码在VS中是没有任何问题的,但是在其他编译器中可能就会发生错误。其中的原因在 strcmp 函数的返回值上,我们说当前面的字符串大于后面的字符串时返回一个正值,但这个正值可以是任意正值,而在VS上规定这个正值为1,但是在其他编译器上并不见得这个正值都为1。

        6.2 strcmp 的模拟实现

        有了前几个模拟实现字符串函数的经验,模拟 strcmp 函数难度也不是太大。 

#include <stdio.h>
#include <assert.h>int my_strcmp(const char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);while (*str1 == *str2){if (*str1 == '\0'){return 0;}str1++;str2++;}if (*str1 > *str2){return 1;}else{return -1;}
}int main()
{char str1[] = "abcdef";char str2[] = "abcijk";int ret = my_strcmp(str1, str2);printf("%d\n", ret);return 0;
}

        特别的,还可以简化成下面的形式。

7、strncpy、strncat 和 strncmp

        出了 strcpy、strcat 和 strcmp 外,C语言还提供了更加灵活的 strncpy、strncat 和 strncmp,它们算是前三者的升级版,使用起来更加灵活。以 strncpy 为例:

        可以看到 strncpy 相较于 strcpy 多了一个参数,用于指定拷贝多少个字符。另外两个也是类似。

        虽然它们的逻辑表面上看起来是一样的,但是 strcnpy 和 strncat 之间还是有一点差异的

 

 

        可以看到 strncpy 不会给目标字符串主动添加 ‘\0’,但 strncat 就会主动给目标字符串添加 ‘\0’,这是两个函数间的差异。 

        那既然有了 strncat 函数,我们就能弥补上一小节中未能实现字符串自己拼接到自己后面的遗憾了。

8、strtok 函数的使用      

        更多详细介绍请跳转阅读 —> strtok, strtok_s - cppreference.com   

         看了上面的介绍好像还是云里雾里的,我用通俗的话来解释一下。delim 指向一个字符串,定义了用作分隔符的字符集合;第一个参数指定一个字符串,它包含了0个或多个由delim字符串中的一个或多个分隔符分割的标记;strtok 函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针(strtok 函数会改变被操作的字符串,所以被 strtok 函数切分的字符串一般都是临时拷贝的内容并且可修改);strtok 函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok 函数将保存它在字符串中的位置;strtok 函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记;如果字符串中不存在更多标记,则返回NULL指针。也就是说,只需要传递一次指向字符串的非空指针,剩下的都传空指针。

        上面的描述其实说的是  strtok 函数是一个过滤指定字符,提取出你想要的部分的函数。比如,有一个邮箱地址 18655404590@163.com,我们想要剔除其中的特殊字符 ‘@’ 和 ‘.’ ,提取出18655404590、163和com,那我们就可以使用 strtok 函数来实现。其中字符指针str指向目标字符串“18655404590@163.com”,delim 指向指定的分隔符“@、.”。

        但是,上面是我们事先知道字符串中有两个分隔符,所以写了三个打印函数,那如果我们不知道一个字符串中有多少个分隔符呢?这里可以用for循环来解决,之前我们在介绍for循环的文章中说过这么一句话,for循环通常用来解决循环次数未知的情况。

 

 9、strstr 的使用和模拟实现

        9.1 strstr 的使用

        更多详细介绍请跳转阅读 —> strstr - cppreference.com                简单来说,strstr 函数的作用是在一个字符串中查找另一个字符串,找到了就返回这个字符串第一次出现的起始地址,没找到就返回一个空指针。来看示例:

        9.2 strstr 的模拟实现

        模拟实现 strstr 函数之前,我们需要想清楚怎么在一个字符串中找另一个字符串是否存在呢?容易想到的是两个字符串通过指针解引用来一个一个的比较来判断是否存在一个相同的字符串,大致思路如下:

        (1)逐个字符地访问被查找的字符串,当访问到与目标字符串首字符相同的字符时记住这个可能的地址,方便后面返回;

        (2)当两个字符串的字符两两比较一直到目标字符串访问到 ‘\0’ 时说明找到了,返回之前记住的地址;

        (3)当被查找的字符串访问到 ‘\0’ 时说明被查找的字符串不存在,返回一个空指针;

        (4)综上,需要创建三个指针,其中两个指向被查找字符串,一个用来逐个访问字符,一个用来记住可能的地址,第三个指针指向目标字符串并且在改变了指针的指向后重新让其指向目标字符串的首地址。

#include <stdio.h>
#include <assert.h>char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = NULL;const char* s2 = NULL;const char* cur = str1;//用于返回可能的地址if (*str2 == '0')//当目标字符串是空字符串时{return cur;}while (*cur != '\0'){   s1 = cur;s2 = str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')//找到了目标字符串{return cur;}cur++;}return NULL;//没找到
}int main()
{char str1[] = "abcdddeab";char str2[] = "deab";char* ps = my_strstr(str1, str2);if (NULL == ps){printf("不存在\n");}else{printf("%s\n", ps);}return 0;
}

10、 strerror 函数的使用

        更多详细介绍请跳转阅读 —> strerror, strerror_s, strerrorlen_s - cppreference.com

 

         简单地说,strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。

        在不同的系统和C语言标准库的实现中都规定了一些错误码,一般是放在 errno.h 这个头文件中说明的,C语言程序启动的时候就会使用一个全局的变量 errno 来记录程序当前的错误码,只不过程序启动的时候 errno 是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会将对应的错误码存放在 errno 中,而一个错误码的数字是整数很难理解是什么意思,所以每一个错误码都是有对应的错误信息的,strerror 函数就可以将错误对应的错误信息字符串的地址返回来。

         整数0~10对应的错误信息如下:

         再来举一个例子,其中涉及到一些我们之前还没学到的内容,请不要在意,主要是 strerror 函数的用法。

         C语言函数中还有一个函数和 strerror 函数的功能是相似的,它就是 perror 函数。来看一下它的介绍:

        它和 strerror 函数的区别在哪里呢?

        strerror 函数的功能是将错误码对应的错误信息的字符串的地址返回,而 perror 函数的功能是将 errno 中错误码对应的错误信息打印出来。那它是怎样打印的呢?perror 函数打印的规则是先打印字符指针s指向的字符串,再打印一个冒号和一个空格,然后打印错误码对应的错误信息。 

        可以看到上面 printf 函数和 perror 函数打印的内容是一样的。

        也就是说 perror == printf + strerror。我们可以根据自己的选择选用这两个函数。

        如果觉得我的文章还不错,请点赞、收藏 + 关注支持一下,我会持续更新更好的文章。  

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

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

相关文章

Pinia(三): 了解和使用state

1.state state 就是我们要定义的数据, 如果定义 store 时传入的第二个参数是对象, 那么 state 需要是一个函数, 这个函数的返回值才是状态的初始值.这样设计的原因是为了让 Pinia 在客户端和服务端都可以工作 官方推荐使用箭头函数(()>{ })获得更好的类型推断 import { de…

最新张量补全论文收集【8篇】

目录 1、利用张量子空间先验&#xff1a;增强张量补全的核范数最小化和 2、基于可学习空间光谱变换的张量核范数多维视觉数据恢复 3、用于图像补全的增强型低秩和稀疏 Tucker 分解 4、多模态核心张量分解及其在低秩张量补全中的应用 5、 低秩张量环的噪声张量补全 6、 视…

三十四、openlayers官网示例Dynamic clusters解析——动态的聚合图层

官网demo地址&#xff1a; https://openlayers.org/en/latest/examples/clusters-dynamic.html 这篇绘制了多个聚合图层。 先初始化地图 &#xff0c;设置了地图视角的边界extent&#xff0c;限制了地图缩放的范围 initMap() {const raster new TileLayer({source: new XYZ…

JAVA流程控制break,continue,goto

1.break在任何循环语句的主体成分&#xff0c;均可用break控制循环的流程。break用于强行退出循环&#xff0c;不执行循环中剩余的语句。&#xff08;break语句也在switch语句中使用&#xff09; 如图&#xff1a;break语句强行退出循环&#xff0c;结果输出1~30便结束&#xf…

两数之和-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第76讲。 两数之和&#xf…

结构体(1)

结构体: 记录班级的学生的信息: 姓名 数组 char name[30][100]; // 性别 char sex[30]; // 0 1 年龄 int age[30]; 学号 int sno[30]; 打印 小明 同学 信息 c语言 --- 提供了一种方式&#xff0c;可以让用户自定义数据类型 &#xff1a; 构造一个数据类型 …

Java面试八股之死锁和活锁的区别

死锁和活锁的区别 基本定义&#xff1a; 死锁&#xff08;Deadlock&#xff09;&#xff1a;指两个或多个线程互相等待对方释放资源&#xff0c;从而导致所有线程都无法继续执行的状态。每个线程至少持有一个资源&#xff0c;并等待另一个由其他线程持有的资源&#xff0c;形…

初始操作系统

概念&#xff1a; 1.系统资源的管理者&#xff1a;实质控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机地工作和资源的分配 2.向上层提供方便易用的服务&#xff1a;以提供给用户和其他软件方便接口和环境 封装思想&#xff1a;操作系统把一些丑…

Oracle数据库面试题-2

21. 请解释Oracle数据库中的自动存储管理(ASM)的概念。 Oracle数据库中的自动存储管理(ASM) 自动存储管理(ASM)是一种Oracle数据库的存储管理解决方案,它使得数据库管理员能够集中管理多个物理磁盘驱动器,提供了一系列高级功能,如磁盘组、冗余和备份等。ASM简化了存…

阿里云服务器接入百度云防护后显示502原因

最近&#xff0c;发现很多使用了阿里云服务器的网站出现502的情况 经百度云防护技术排查发现阿里云机房对百度云防护的IP进行了拦截&#xff0c;原因近期可能是百度云防护的IP请求过于频繁&#xff0c;导致阿里云机房策略把百度云的IP当成了攻击IP。 解决办法是提交工单让阿里…

第三方模块的下载与安装

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在进行Python程序开发时&#xff0c;除了可以使用Python内置的标准模块外&#xff0c;还有很多第三方模块可以被我们所使用。对于这些第三方模块&…

python过滤数组中的空字符串

20240603 - 解决方案 对于一个字符串数组&#xff0c;想要过滤其中的空字符串的时候。 问答一中提供了几种方案&#xff1a; str_list filter(None, str_list) str_list filter(bool, str_list) str_list filter(len, str_list) str_list filter(lambda item: item, st…

关于AI数字人的几个创作平台及其使用(二)

文章目录 二、创作平台二1、基本信息2、使用方法1、进入创作页面2、开始创作2.1、脚本创作2.1.1、使用文本软件创作2.1.2、AI创作脚本2.2、选择模板2.2.1、选择模板2.2.2、字幕与配音2.3、细节调整2.3.1、数字人2.3.2、音乐2.3.3、背景2.3.4、文字2.3.5、贴图2.3.6、智能配图或…

5.31——进军MYSQL

目录 简略版&#xff1a; 详解版&#xff1a; 一. myaql概述&#xff1a; 数据库&#xff1a; 数据库管理系统&#xff1a; SQL&#xff1a; 二. masql的安装&#xff1a; 启动与停止&#xff1a; 1. MYSQL提供的命令行 2. windows提供的命令行工具 三.数据模型 …

在一个定义好的数据对象(class)中,后续更新时只更新其中部分数据,其余部分会恢复初始设置吗

在一个定义好的数据对象&#xff08;class&#xff09;中&#xff0c;后续更新时只更新其中部分数据&#xff0c;其余部分会恢复初始设置吗 在一个定义好的数据对象&#xff08;class&#xff09;中&#xff0c;如果你只更新其中部分数据&#xff0c;其余部分的值不会恢复到初始…

Claude 3可使用第三方API,实现业务流程自动化

5月31日&#xff0c;著名大模型平台Anthropic宣布&#xff0c;Claude3模型可以使用第三方API和工具。 这也就是说&#xff0c;用户通过文本提问的方式就能让Claude自动执行多种任务&#xff0c;例如&#xff0c;从发票中自动提取姓名、日期、金额等&#xff0c;该功能对于开发…

DVWA靶场搭建:Apache、MySQL、PHP、DVWA

最近为了能够较为真实地学习Web渗透的各种技术&#xff0c;就想着自己搭建一个专门用于学习的Web演练平台--DVWA“靶场”。 DVWA可以进行暴力&#xff08;破解&#xff09;、命令行注入、跨站请求伪造、文件包含、文件上传、不安全的验证码、SQL注入、SQL盲注、弱会话ID、XSS漏…

批量归一化(BN)和层归一化(LN)的区别

批量归一化&#xff08;Batch Normalization, BN&#xff09;和层归一化&#xff08;Layer Normalization, LN&#xff09;是深度学习中常用的两种归一化技术&#xff0c;它们主要用于解决训练过程中的内部协变量偏移问题&#xff0c;加速模型收敛和提高稳定性。 1. 为什么需要…

田忌赛马

题目描述 你要和田忌赛马。你们各自有 &#x1d441;N 匹马&#xff0c;并且要进行 &#x1d441;N 轮比赛&#xff0c;每轮比赛&#xff0c;你们都要各派出一匹马决出胜负。 你的马匹的速度分别为 u1​,u2​,⋯&#xff0c;un​&#xff0c;田忌的马匹的速度分别为 v1​,v2​…