详解字符串函数<string.h>(下)

1. strncpy函数的使用和模拟实现

char* strncpy(char* destination, const char* source, size_t num)

1.1 函数功能以及用法

 拷贝指定长度的字符串

将“source”指向的字符串中的“num”个字符拷贝到“destination”指向的字符数组中。相比于strcpy函数,该函数多了一个参数“num”,表示要拷贝字符的个数。这样一来,就不会因为检索不到'\0'而越界访问了,相对安全,且更加灵活。

1.2 函数的原理

在strcpy的基础之上,另外设置一个判断条件,使得当拷贝完“num”个字符之后,函数就会停止拷贝。

1.3 注意事项

如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

1.4 模拟实现

char* my_strncpy(char* dest, const char* src, size_t num)
{assert(dest && src);char* ret = dest;int flag = 0;while(num--){if(*dest == '\0')flag = 1;if(*src == '\0')*dest++ = *src;else*dest++ = *src++;}if(flag)*dest = '\0';return ret;
}

2. strncat函数的使用和模拟实现

char* strncat(char* destination, const char* source, size_t num)

2.1 函数功能以及用法

追加指定长度的字符串

将“source”指向的字符串中的“num”个字符追加到“destination”指向的字符数组中。相比于strcat函数,同样多了一个参数“num”。

2.2 函数的原理

在strcat的基础之上,另外设置一个判断条件,使得当追加完“num”个字符之后,函数就会停止追加。

2.3 注意事项

如果“source” 指向的字符串的⻓度⼩于“num”的时候,只会将字符串中到 '\0' 的内容追加到“destination”指向的字符串末尾,也就是不会额外补充'\0'。

2.4 模拟实现

char* my_strncat(char* dest, const char* src, size_t num)
{assert(dest && src);char* ret = dest;while(*dest != '\0'){dest++;}while(num--){*dest++ = *src++;if(*src == '\0')break;}*dest = '\0';
}

3. strcmp函数的使用和模拟实现

int strncmp(const char* str1, const char* str2, size_t num)

没什么好说的直接看模拟实现吧

int my_strncmp(const char* str1, const char* str2, size_t num)
{assert(str1 && str2);while(*str1 == *str2 && num--){if(*str1 == '\0')return 0;str1++;str2++;}return (*str1 - *str2);
}

4. strstr函数的使用和模拟实现

char* strstr(const char* str1, const char* str2)

4.1 函数的功能以及用法

查找子字符串

在“str1”指向的字符串中查找是否有“str2”指向的字符的存在。在使用时,要求用户输入两个字符串的起始位置,找到时返回str2在str1中的起始位置,找不到返回空指针。

#include <stdio.h>
#include <string.h>int main()
{char email[] = "3143884180@qq.com";char substr[] = "@qq.com";char* ret = strstr(email, substr);if(ret == NULL){printf("子串不存在\n");}else{printf("%s\n", ret);}return 0;
}

4.2 函数的原理

首先在str1中查找str2的首字符,找到之后检验紧跟着的内容是否与str2完全相同,若相同则返回该相应的地址;若不相同则继续在str1中查找str2的首字符,直到排查完str1中所有可能的位置。

4.3 注意事项

字符串的⽐较匹配不包含 '\0' 字符,以 '\0' 作为结束标志

4.4 模拟实现

char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);while(*str1)//当*str1为'\0'时循环结束,返回NULL{while(*str1 != *str2)//找到第一个字符相等的位置{str1++;if(*str1 == '\0')return NULL;}const char* str3 = str1;const char* str4 = str2;while(*str3++ == *str4++)//检查改位置是否符合条件{if(*str4 == '\0')return (char*)str1;}str1++;//未返回说明不符合,第一个指针移动一次}return NULL;
}

5.strtok函数的使用和模拟实现

char* strtok(char* str, const char* sep)

5.1 函数的功能以及用法

字符串分割

依据用户提供的分隔符,将字符串分隔为几个部分。

1. sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合

2. 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。

3. strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。

4. strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。

5. strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。

6. 如果字符串中不存在更多的标记,则返回 NULL 指针。

int main()
{const char* sep = "@.";char email[] = "3143884180@qq.com";char cp[30] = {0};strcpy(cp, email);char* ret = strtok(cp, sep);if(ret != NULL)printf("%s\n", ret);ret = strtok(NULL, sep);if(ret != NULL)printf("%s\n", ret);ret = strtok(NULL, sep);if(ret != NULL)printf("%s\n", ret);return 0;
}

如图,在sep中定义了分隔符“@”和“.”。

第一次调用,将cp的地址传入,函数在字符串“3143884180@qq.com”中找到“@”,将其替换为'\0'并返回指向“3143884180”的指针。同时,函数已经记录下这个'\0'的地址。

第二,三次调用,将NULL传入,函数通过自己记录下的位置,开始查找下一个分隔符。

该代码还可简写为

int main()
{const char* sep = "@.";char email[] = "3143884180@qq.com";char cp[30] = {0};strcpy(cp, email);char* ret = NULL;for(ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}return 0;
}

5.2 函数的原理

首先检查第一个参数是否为NULL,若是则用记录好的位置将其替换。然后在字符串中查找分隔符,将其替换为'\0'后用static修饰的变量记录并返回字符串的起始位置。

5.3 注意事项

strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。

5.4 模拟实现

char* my_strtok(char* str, const char* sep)
{assert(sep);static char* tmp = NULL;if(str == NULL && tmp == NULL)return NULL;if(str == NULL)str = tmp + 1;char* ret = str;for(int i = 0; str[i] != '\0'; i++){for(int j = 0; sep[j] != '\0'; j++){if(str[i] == sep[j]){str[i] = '\0';tmp = str + i;return ret;}}}tmp = NULL;return ret;
}

6.strerror函数的使用

char * strerror ( int errnum )

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

#include <errno.h>
#include <string.h>
#include <stdio.h>int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}

0. No error-----------------------------------------无错误

1. Operation not permitted--------------------不允许操作

3. No such file or directory--------------------没有这样的文件或目录

4. No such process-----------------------------没有这样的进程

5. Interrupted function call--------------------函数调用中断

6. Input/output error----------------------------输入/输出错误

7. No such device or address----------------没有这样的设备或地址

8. Arg list too long-------------------------------参数列表太长

9. Exec format error----------------------------执行格式错误

10. Bad file descriptor--------------------------错误的文件描述符

11. No child processes-------------------------无子进程

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

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

相关文章

SQL语言的五大分类 (DQL、DDL、DML、DCL、TCL)

目录 一、DQL 二、DDL 三、DML 四、DCL 五、TCL 一、DQL&#xff08;数据查询语言&#xff09; Data Query Language&#xff0c;数据查询语言&#xff1a; select&#xff1a;用于数据查询 关键字&#xff1a;SELECT ... FROM ... WHERE 二、DDL&#xff08;数据定义语…

swift 长按桌面图标弹出快捷选项

文章目录 一、3D Touch二、主屏交互1. 静态添加2. 动态添加三、监听主屏交互按钮的点击事件四、预览和跳转1. 注册3D touch2. 实现协议3. 在目标控制器复写previewActionItems4. 使用UIContextMenuConfiguration一、3D Touch 3D Touch通过屏幕下方的压力感应器来感知不同的压力…

Cesium地表透明

之前Cesium是不能地表透明的&#xff0c;需要改内部代码&#xff0c;将GlobeSurfaceTileProvider.js中的PASS.GLOBE改成PASS.TRANSPARENT&#xff0c;通过将地表的drawCommand放到透明队列里渲染。现在发现有了新的方法&#xff08;其实2020年就有该方法了&#xff09;&#xf…

数据库管理-第157期 Oracle Vector DB AI-08(20240301)

数据库管理157期 2024-03-01 数据库管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09;1 创建示例向量2 查找最近向量3 基于向量簇组的最近向量查询总结 数据库管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09; 作者&…

【axiox】前后端接口通讯数据交互

重要全局配置&#xff1a; axios.create(); 设置axios请求的公共配置信息。 service.interceptors.request.use((config)>{}) 请求拦截器 service.interceptors.response.use((res)>{},(err)>{}) 响应拦截器 const source axios.CancelToken.source(); 用…

oracle RAC节点重构

一、清除集群上二节点的节点信息 1、删除实例 dbca或静默&#xff1a; [oraclerac1 ~]$ dbca -silent -deleteinstance -nodelist rac2 -gdbname orcl -instancename orcl2 -sysdbausername sys -sysdbapassword oracledbca-实例管理-删除节实例-选择服务输入密码-选择inactiv…

基于小波神经网络的数据分类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 1.程序功能描述 基于小波神经网络的数据分类算法。输入为5个特征值&#xff0c;输出为判断&#xff08;是&#xff0c;否&#xff09;。拿50组数据对本算法作为训练组&#xff0c;后30组数据作…

B树、B+树、红黑树的定义、之间的区别、优缺点、数据结构、应用等

目录 B树 定义 数据结构 优点 缺点 应用 B树 定义 数据结构 优点 缺点 应用 红黑树 定义 数据结构 优点 缺点 应用 B树与B树与红黑树的区别 B树 定义 B树是一种自平衡的多路搜索树&#xff0c;它可以有多个子节点&#xff0c;不同于二叉树的是&#xff0c;一…

深入学习NumPy库在数据分析中的应用场景

在数据科学与机器学习领域&#xff0c;NumPy&#xff08;Numerical Python&#xff09;是一个经常被提及的重要工具。它是Python语言中一个非常强大的库&#xff0c;提供了高性能的多维数组对象以及用于处理这些数组的工具。NumPy不仅仅是一个用于数值计算的库&#xff0c;它还…

【PCB】用透明胶带制作印制板

用透明胶带作保护层来制作印制电路的方法&#xff0c;简单实用&#xff0c;作出的电路板质量较好&#xff0c;具体作法如下&#xff1a; &#xff08;1&#xff09;裁下一块敷铜板&#xff0c;用水磨砂纸将其四周毛刺磨平&#xff0c;用去污粉处理敷铜板表面上的污垢&#xff…

基于粒子群优化算法的图象聚类识别matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于粒子群优化算法的图象聚类识别。通过PSO优化方法&#xff0c;将数字图片的特征进行聚类&#xff0c;从而识别出数字0~9. 2.测试软件版本以及运行结果展示 M…

Hadoop之HDFS——【模块一】元数据架构

一、元数据是什么 在HDFS中,元数据主要指的是文件相关的元数据,通过两种形式来进行管理维护,第一种是内存,维护集群数据的最新信息,第二种是磁盘,对内存中的信息进行维护与持久化,由namenode管理维护。从广义的角度来说,因为namenode还需要管理众多的DataNode结点,因…

【测试开发面试复习(一)】计算机网络:应用层详解(P2)补充ing

复习自用&#xff0c;若有错漏&#xff0c;欢迎一起交流一下~~ 一、高频面试题记录 uri 和 url 的区别 &#xff1f; dns 是啥工作原理&#xff0c;主要解析过程是啥&#xff1f; 用户输入网址到显示对应页面的全过程是啥&#xff1f; http 头部包含哪些信息&#xff1f; http…

IEEE Trans. On Robotics ​“受护理人员启发的双臂机器人穿衣”研究工作

开发能够协助穿衣的辅助机器人&#xff0c;可以极大地改善老年人和残疾人的生活。然而&#xff0c;大多数机器人穿衣策略只考虑使用单个机器人&#xff0c;这大大限制了穿衣辅助的性能。事实上&#xff0c;专业护理人员是通过双臂来完成这项任务的。受其启发&#xff0c;我们提…

【YOLO v5 v7 v8 小目标改进】Non-local 注意力实现非局部神经网络,解决长空间和时间数据依赖问题

Non-local 注意力实现非局部神经网络&#xff0c;解决长空间和时间数据依赖问题 提出背景长距离技术对比Non-local Block是怎么设计Non-local 神经网络效果 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 提出背景 论文&#xff1a;https://arxiv.org/pdf/1711.07971.pdf …

用 tensor-parallel 多卡并发推理大模型

利用 tensor-parallel 把模型训练与推理的 workload 平均分布到多块 GPU&#xff0c;一方面可以提高推理速度&#xff0c;另一方面 vram 的负载平衡也让复杂的 prompt 能被轻松处理。 import 相关的 libs&#xff1a; # torch version 2.0.0 import torch # tensor-parallel …

抽象类与抽象方法

文章目录 抽象类抽象类的特点 抽象方法抽象方法的特点 模板设计模式模板设计模式能解决的问题示例 #抽象类与抽象方法 抽象类 用abstract关键字来修饰一个类时&#xff0c;这个类就叫抽象类。 public abstract 类名{... }抽象类的特点 1&#xff09;抽象类不能被实例化。 2&…

AOP(黑马学习笔记)

AOP基础 学习完spring的事务管理之后&#xff0c;接下来我们进入到AOP的学习。 AOP也是spring框架的第二大核心&#xff0c;我们先来学习AOP的基础。 在AOP基础这个阶段&#xff0c;我们首先介绍一下什么是AOP&#xff0c;再通过一个快速入门程序&#xff0c;让大家快速体验A…

JAVASE初认识

1.初认识其结构 1.源文件&#xff08;扩展名为*.java)&#xff1a;源文件带有类的定义。类用来表示程序的一个组件&#xff0c;小程序或许只会有一个类。类的内容必须包含在花括号里面。 2.类&#xff1a;类中带有一个或多个方法。方法必须在类的内部声明。 3.方法&#xff1…

vue3创建h5 项目使用rem做响应式的配置

第一步 安装依赖&#xff1a; npm install amfe-flexible -S npm install postcss-px2rem -S第二步 main.ts文件中导入 import "amfe-flexible/index.js";第三步 进行配置&#xff1a; vue3 项目中创建 postcss.cinfig.js文件&#xff0c;这里是基于设计稿是750px…