【C语言】strncpy,strncat,strncmp,memcpy,memmove,memcmp,memset的模拟实现

本文详细介绍了C语言中strncpy、strncat、strncmp、memcpy、memmove、memcmp、memset和strchr等字符串处理函数的概念、用法、潜在问题,包括内存溢出、比较准确性及性能影响,提醒开发者注意内存安全和效率优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前些天发现了一个巨牛的 人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到 网站


首先注意,接下来的函数基本都需要目标内存块足够大。
如果不够大很有可能会产生下述情况:

  1. 比较结果不准确:如果目标函数不够大,比较的字符数量较少,可能无法完整比较两个字符串的内容。这样就无法得到正确的比较结果,可能会导致程序逻辑错误。
  2. 隐患安全问题:如果目标函数不够大,比较的字符数量小于其中一个字符串的长度,可能会导致缓冲区溢出的安全问题。因为在比较过程中,如果需要比较的字符串长度超过了目标函数的大小,就会访问到未分配的内存空间,可能导致程序崩溃或者被攻击者利用。
  3. 性能影响:如果目标函数不够大,比较的字符数量较少,可能需要多次调用strncmp函数才能完成完整的字符串比较。这样会增加函数调用的开销和执行时间。

strncpy(替换掉原有字符串的指定位置)

概念
在这里插入图片描述
上面这张图是MSDN上对strncpy所需要的形参类型以及返回类型的介绍,我们可以知道,这个函数的头文件为<string.h>,需要输入一个目标地址,一个源头地址,以及拷贝多少个字符,最后返回的是一个字符指针

(关于指针的一些详细介绍,本人主页有,不嫌弃可以看看下)

在这里插入图片描述

然后这张是这个函数的一个实现案例,它先把"Dogs"的4个字符全部拷贝到string里,再把"mean"的四个字符拷贝到string+9的位置,随后实现了string里字符串的变化

在这里插入图片描述
这里是cpluscplus对strncpy的注意声明,大概意思如下

  • 拷贝num个字符从源字符串到目标空间。
  • 如果在复制num个字符之前找到源C字符串的结尾(由null字符表示),则目的地将用零填充,直到向其写入总数为num个字符。
  • 如果source长度大于num,则不会在destination的末尾隐式添加空字符。因此,在这种情况下, destination不应被视为以空结尾的C字符串(这样读取会溢出)。
  • destination和source不应重叠(重叠时,请参阅memmove以获得更安全的替代方法)。

实现
这个函数的实现较简单,只需要找对destination和source的位置,然后用佛如循环一个一个改变,唯一要注意的是,因为再循环后往往destination的地址惠王后偏移num个长度,所以需要提前备份一个destination的地址

代码如下

char* my_strncpy(char* dest, const char* src, int numsSize)
{
   
	char* cp = dest;
	while (numsSize--)
	{
   
		*dest++ = *src++;
	}
	return cp;
}

strncat(追加指定长度的字符串到原有的字符串后面)

概念
在这里插入图片描述
上面这张图是MSDN上对strncat所需要的形参类型以及返回类型的介绍,我们可以知道,这个函数的头文件为<string.h>,需要输入一个目标地址,一个源头地址,以及拷贝多少个字符,最后返回的是一个字符指针,基本和strncpy一样

在这里插入图片描述

  • 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字
  • 如果source指向的字符串的长度小于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾

在这里插入图片描述
这是MSDN上的案例,不过多赘述。
实现

这里除了跟strncpy一样需要提前备份一次,还需要通过循环*dest++达到destination字符串最后一位的效果,并且如果source指向的字符串的长度小于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾,需要在返回前加上一个’\0’

代码如下

char* my_strncat(char* dest, char* src, size_t num)
{
   
	char* ret = dest;
	assert(dest && src);
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值