赶紧来修炼内功~字符串函数详解大全(二)

2023-11-12

目录

1.strncpy

重点:

 模拟实现:

 2.strncat

重点:

模拟实现: 

3.strncmp

 重点:

 模拟实现:

写在最后:


1.strncpy

该函数包含三个参数,前两个参数与上一篇文章中讲解的strcpy函数一样,一个目的地,一个源,第三个为要拷贝的字节数 (注意这里是字节数!)

重点:

1. 拷贝num个字符从源字符串到目标空间。

2. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。 

 1.

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[15] = "abcdefghij";
	char arr2[] = "1234";
	strncpy(arr1, arr2, 4);
	printf("%s\n", arr1);
	return 0;
}

 

从arr2中拷贝4个字节的内容到arr1,只会覆盖掉前4个字节的内容,不会全部覆盖。

2. 

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[15] = "abcdefghij";
	char arr2[] = "1234";
	strncpy(arr1, arr2, 6);
	printf("%s\n", arr1);
	return 0;
}

 这里我们要从arr2中拷贝6个字节的内容到arr1,但是arr2中只有4个字节的内容,所以拷贝完arr2的内容后要在后面追加两个0;

'\0'的ASCII码值就是0,所以打印arr1时,会提前终止打印。

 模拟实现:

创建一个my_strncpy函数,模拟实现strncpy函数的功能:

其实与模拟实现strcpy函数类似,只不过多了一个控制拷贝多少个字节的参数而已~

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* dest, const char* src, size_t num)//返回值类型参数类型与原函数保持一致
{//dest所指向的字符串需要被修改,不用const保护,src所指向的字符串不需要被修改用const修饰保护
	assert(dest && src);//断言一下,保证两个指针均不为空指针,若为空指针则中止程序并报错
	char* ret = dest;//创建一个char*变量保存起始地址,后面需要返回起始地址
	while (num--)  //控制拷贝几个字节
	{
		*dest = *src;  //拷贝
		if (*src != '\0') //若src所指向的字符串没有到'\0'就继续++
			src++;        //++,指向下一个字符
		dest++;           //++,指向下一个字符
	}
	return ret; //返回字符串起始位置
}
int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "1234";
	printf("%s\n", my_strncpy(arr1, arr2, 6));
	return 0;
}

 2.strncat

该函数包含三个参数,前两个参数与上一篇文章中讲解的strcat函数一样,一个目的地,一个源,第三个为要追加的字节数 (注意这里是字节数!)

重点:

1. 在目标字符串后面追加num个字节

2. 追加是从目标字符串最后的'\0'开始追加的,同时追加完成后会自动在最后补上一个'\0'

3. 如果源字符串的长度小于num,则就只追加完源字符串,再补上一个'\0'就结束了

4. 可以用该函数自己给自己追加

 1.

int main()
{
	char arr1[15] = "abcdef";
	char arr2[] = "abcd";
	strncat(arr1, arr2, 2);
	printf("%s\n", arr1);
	return 0;
}

在arr1后面追加两个字节的arr2的内容。

2.

 

 由上面两个步骤的对比,可以很清晰地看出追加是从目标字符串最后的'\0'开始追加的。 

int main()
{
	char arr1[15] = "abcdef\0xxxx";
	char arr2[] = "abcd";
	strncat(arr1, arr2, 2);
	printf("%s\n", arr1);
	return 0;
}

 在arr1字符串中间加上一个'\0'那么就会从这个'\0'处开始追加,我们可以看到追加完"ab"后,又追加了一个'\0'。

 3.

int main()
{
	char arr1[15] = "abcdef\0xxxxxx";
	char arr2[] = "abcd";
	strncat(arr1, arr2, 6);
	printf("%s\n", arr1);
	return 0;
}

  如果源字符串的长度小于num,则就只追加完源字符串,再补上一个'\0'就结束了

4.

int main()
{
	char arr[10] = "abc";
	strncat(arr, arr, 3);
	return 0;
}

 用该函数自己给自己追加是安全的

模拟实现: 

创建一个my_strncat函数,模拟实现strcat函数的功能:

char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* ret = dest;     //上面的代码与前一个模拟实现的函数原因相同,这里就不多赘述了
	while (*dest != '\0') //找到dest指针指向的字符串的末尾的'\0'
		dest++;
	while (num--)         //控制追加几个字节
	{
		*dest = *src;     //追加
		if (*src == '\0') //若src指向'\0',就直接返回终止函数,此时'\0'已经追加完成了
			return ret;
		dest++;           //++,指向下一个字符
		src++;            //++,指向下一个字符
	}
	*dest = '\0';         //追加完成后再在最后追加一个'\0'
	return ret;           //返回字符串的起始地址
}
int main()
{
	char arr1[15] = "abcdef\0xxxxxx";
	char arr2[] = "1234";
	printf("%s\n", my_strncat(arr1, arr2, 3));
	return 0;
}

3.strncmp

 该函数包含三个参数,前两个参数与上一篇文章中讲解的strcmp函数一样,一个目的地,一个源,第三个为要比较的字节数 (注意这里是字节数!)

返回值为int类型,与strcmp函数一样,

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字

 重点:

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

 1. 当两个字符串前num个字符相等时

 2. 当前一个字符串大于后者时

 3. 当前一个字符串小于后者时

 模拟实现:

创建一个my_strncmp函数,模拟实现strncmp函数的功能:

int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);   //上面的代码与前一个模拟实现的函数原因相同,这里就不多赘述了
	while (num--)           //控制比较的字节数
	{
		if (*str1 == *str2)  //比较字符
		{
			if (*str1 == '\0')//判断是否已经比较到了末尾,若为'\0'则表示两字符串相等
				return 0;
			str1++;
			str2++;
		}
		else
			return *str1 - *str2;//若两字符不同就直接返回两字符差值
	}
	return 0;  //若能走到这就说明两字符串所比较的这几个字节的字符时相同的
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abccdg";
	printf("%d\n", my_strncmp(arr1, arr2, 4));
	return 0;
}

写在最后:

本节内容已经讲完,下篇会继续讲解字符串相关函数,期待围观学习!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

赶紧来修炼内功~字符串函数详解大全(二) 的相关文章

  • setContextProperty 和对象的 setProperty 之间的区别

    我现在真的很困惑 有什么区别 QQmlApplicationEngine engine engine rootContext setContextProperty myObject userData and object gt setPro
  • 如何将包含 5000 条记录的 Excel 文件插入到 documentDB 中?

    我有一个 Excel 文件 最初约有 200 行 我能够将 Excel 文件转换为数据表 并且所有内容都正确插入到 documentdb 中 Excel 文件现在有 5000 行 在插入 30 40 条记录后不会插入 其余所有行不会插入到
  • 为什么 VB.NET 和 C# 中针对值检查 null 存在差异?

    In VB NET http en wikipedia org wiki Visual Basic NET有时候是这样的 Dim x As System Nullable Of Decimal Nothing Dim y As System
  • 使用API​​隐藏程序标题栏

    它可以使用 c 和 windows api 删除窗口控制台标题栏 如果是的话如何 请 这个简单的应用程序隐藏并显示其所在控制台的标题栏 它会立即将控制台标题更改为 guid 以查找窗口句柄 然后 它使用 ToggleTitleBar 使用找
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • 如何在 Asp.net Gridview 列中添加复选框单击事件

    我在 asp 中有一个 gridview 其中我添加了第一列作为复选框列 现在我想选择此列并获取该行的 id 值 但我不知道该怎么做 这是我的 Aspx 代码
  • 矩阵向量变换

    我正在编写一个代码来制作软件蒙皮器 骨骼 皮肤动画 并且我正处于 优化 阶段 蒙皮器工作得很好 并且在 Core 上 1 09 毫秒内对 4900 个三角形网格与 22 个骨骼进行蒙皮Duo 2 Ghz 笔记本 我需要知道的是 1 有人可以
  • 是否有像 gccxml 这样的用于生成包装器的 C 标头解析器工具?

    我需要为一种新的编程语言编写一些 C 标头包装器 并且想要类似 gccxml 的东西 但不完全依赖 gcc 以及它在 Windows 系统上带来的问题 只需要读C而不是C 只要有完整的文档记录 任何格式的输出都可以 Linux Solari
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 系统错误 124 - SHFileOperation 的 ERROR_INVALID_LEVEL

    我在使用时遇到问题SHFileOperation SHFileOperation SHFILEOPSTRUCT https stackoverflow com questions 9191415 shfileoperation shfile
  • 允许使用什么类型的内容作为 C 预处理器宏的参数?

    老实说 我很了解 C 编程语言的语法 但对 C 预处理器的语法几乎一无所知 尽管我有时在编程实践中使用它 所以问题来了 假设我们有一个简单的宏 它扩展为空 define macro param 可以放入宏调用构造中的语法有哪些限制 调用宏时
  • 设计 Javascript 前端 <-> C++ 后端通信

    在我最近的将来 我将不得不制作一个具有 C 后端和 Web 前端的系统 要求 目前 我对此了解不多 我认为前端将触发数据传输 而不是后端 所以不需要类似 Comet 的东西 由于在该领域的经验可能很少 我非常感谢您对我所做的设计决策的评论
  • 不兼容的类型 - 是因为数组已经是指针吗?

    在下面的代码中 我创建一个基于书籍结构的对象 并让它保存多个 书籍 我设置的是一个数组 即定义 启动的对象 然而 每当我去测试我对指针的了解 实践有帮助 并尝试创建一个指向创建的对象的指针时 它都会给我错误 C Users Justin D
  • 使用 foreach 循环和 XmlNodeList C# 将新节点附加到节点列表

    目前我处理的是这样的XML类型 XML FILE http 20drive google com open id 0By5BxgNi9eGcRldxcEZNU0FDTzQ 参考XML文件 我想检查一个节点 如果找不到该节点 我必须将该节点附
  • 纯虚函数可能没有内联定义。为什么?

    纯虚函数是那些虚函数并且具有纯说明符 0 第 10 4 条第 2 款C 03 的内容告诉我们什么是抽象类 顺便说一句 如下 注意 函数声明不能 同时提供纯说明符和定义 尾注 示例 struct C virtual void f 0 ill
  • 在 C++ 和 Windows 中使用 XmlRpc

    我需要在 Windows 平台上使用 C 中的 XmlRpc 尽管我的朋友向我保证 XmlRpc 是一种 广泛可用的标准技术 但可用的库并不多 事实上 我只找到一个库可以在 Windows 上执行此操作 另外一个库声称 您必须做很多工作才能
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task

随机推荐

  • 22道高级 React 面试题

    Q1 什么是虚拟DOM 虚拟DOM VDOM 它是真实DOM的内存表示 一种编程概念 一种模式 它会和真实的DOM同步 比如通过ReactDOM这种库 这个同步的过程叫做调和 reconcilation 虚拟DOM更多是一种模式 不是一种特
  • 【JavaDebug(二)】之Mysql语法异常java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; chec

    本文章由公号 开发小鸽 发布 欢迎关注 老规矩 妹妹镇楼 一 异常 一 异常描述 java sql SQLSyntaxErrorException You have an error in your SQL syntax check the
  • 【binkw32.dll下载】binkw32.dll缺失怎么办

    binkw32 dll文件对一些电脑软件 电脑游戏等程序的正常运行起到关键性作用 对于弹出缺少此类文件的弹窗 用户们很多时候也摸不着头脑 程序明明上次都能正常运行 突然就弹出缺少binkw32 dll文件的提醒窗口 通过小编此次编辑的文章
  • 修改DIV滚动条样式

    滚动条样式 div webkit scrollbar 滚动条整体样式 width 5px 高宽分别对应横竖滚动条的尺寸 height 5px div webkit scrollbar thumb 滚动条里面小方块 border radius
  • 剖析ElasticSearch的评分计算过程

    剖析elasticsearch的评分计算过程 es搜索结果是怎样的排序的 准备测试数据 搜索 剖析参数含义 结论 es搜索结果是怎样的排序的 es的排序准则的相关度 根据搜索 关键词 计算关键词在一个文档中的得分 得分越高结果越靠前 那么计
  • github服务器停止响应,如何解决“git pull,致命:无法访问'https://github.com ... \':服务器空回复”...

    当我使用Git命令 git pull 更新我的存储库时 消息如下 致命 无法访问 来自服务器的空回复 如何解决 git pull 致命 无法访问 https github com 服务器空回复 而且我尝试使用GitHub的应用程序 但此提醒
  • QT5开发之 信号与槽机制

    文章目录 什么是信号与槽 信号与槽原理 如何实现信号与槽机制 实现方式 UI方式 代码方式 QT4 QObject类 connect和disconnect 连接函数 QT4 QT5使用 找到类与类的信号与槽函数 QT4 QT5使用 举例 总
  • Windows下 Cppcheck 的使用教程

    1 Cppcheck是什么 CppCheck是一个C C 代码缺陷静态检查工具 不同于C C 编译器及其它分析工具 CppCheck只检查编译器检查不出来的bug 不检查语法错误 所谓静态代码检查就是使用一个工具检查我们写的代码是否安全和健
  • 计算机窗口移动不了怎么办,电脑鼠标拖不动文件怎么办 电脑鼠标拖动不灵敏如何解决...

    在我们使用电脑的时候 往往都会用到鼠标拖动文件 不知道有没有遇到过电脑鼠标拖不动文件的时候 这种情况大家是怎么解决的呢 不知道没关系 下面小编为大家带来电脑鼠标拖不动文件的解决方法 大家可以按照下面的步骤即可解决 电脑鼠标拖不动文件怎么办
  • 支付宝支付回调,回调日志记录

    1 支付报支付回调方法 public function aliPayNotify try app PayService alipay collect app gt verify collectData collect gt all 获取支付
  • 【Zabbix实战之运维篇】Zabbix监控平台的简单性能调优

    Zabbix实战之运维篇 Zabbix监控平台的简单性能调优 一 Zabbix性能优化介绍 1 造成Zabbix服务器变慢原因 2 Zabbix性能调优的方法 二 检查Zabbix服务器的资源占用情况 1 检查Zabbix各组件容器的资源占
  • [转载]YUV格式纹理贴图的例子

    frameworks native opengl tests gl2 yuvtex gl2 yuvtex cpp 是Android提供的yuv格式纹理贴图的例子 前面先申请存放纹理数据的buffer yuvTexBuffer new Gra
  • 根据哈夫曼树构建哈夫曼编码

    实验题 构造哈夫曼树生成哈夫曼编码 编写一个程序 构造一棵哈夫曼树 输出对应的哈夫曼编码和平均查找长度 并对下表 所示的数据进行验证 单词及出现的频度 单词 The of a to and in that he is at on for H
  • Github下载任意版本的VsCode

    下载历史版本VsCode zip 下载链接由三部分组成 固定部分 commit id VSCode win32 x64 版本号 zip 固定部分 https vscode cdn azure cn stable Commit id 打开 v
  • 嵌入式linux通过systemd自启动一个python代码

    一直想实现一段自启动的代码 今天尝试了下 成功了 做个记录 首先 我用的是imx6ull处理器 嵌入式linux内核版本为4 9 88 然后 上位机用的虚拟机ubuntu22 04 01 先在ubuntu上面试了试 能够自启动 然后再下载到
  • linux系统调用(持续更新....)

    随着自己接触越来越多的linux的系统函数发现自己在linux系统调用方面有很多不足 每次遇到系统调用函数都要百度一遍看一下用法 所以我打算写一篇博客来记录在开发过程遇到的系统调用函数 方便自己查阅 本文持续更新 1 popen 函数 2
  • Unity-协同程序

    知识点一 Unity是否支持多线程 1 首先要明确一点Unity是支持多线程的 只是新开线程无法访问Unity相关对象的内容 Unity中的多线程 要记住关闭 Unity中去使用 如果说 我们一开始在Start内创建一个多线程 那么我们无法
  • 【算法】最近点对问题(暴力破解法)

    简单的画了一张图 通过暴力方式 进行一次比较获取两个点之间的最短距离 点对最近问题 暴力破解法 include
  • Maven Dependency设置,详解!

    come from http www javaeye com topic 240424 用了Maven 所需的JAR包就不能再像往常一样 自己找到并下载下来 用IDE导进去就完事了 Maven用了一个项目依赖 Dependency 的概念
  • 赶紧来修炼内功~字符串函数详解大全(二)

    目录 1 strncpy 重点 模拟实现 2 strncat 重点 模拟实现 3 strncmp 重点 模拟实现 写在最后 1 strncpy 该函数包含三个参数 前两个参数与上一篇文章中讲解的strcpy函数一样 一个目的地 一个源 第三