库函数的模拟实现(strncpy、strncat、strncmp)

前言:

这篇文章我们将会讲到三个库函数的模拟实现,前面文章所讲到的strcpy、strcat、strcmp他们为长度不受限制的字符串函数,而今天要讲到的是长度受限制的字符串函数,因为前面函数的铺垫这次我们三个函数一起讲完。新朋友可以点击链接观看一下之前的库函数模拟实现内容strncpystrcat、strcmp。好的接下来让我们开始本讲的内容

一、strncpy函数说明

还是老规矩cplusplus网址给大家贴在这里,可以自己再进行更深一步的了解。

函数内容总结:

  • 拷贝num个字符从源字符串到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
  • 参数数量不包括'\0'

二、strncpy模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strncpy(char* dest, const char* sour, int num)
{
    assert(dest && sour);
    char* p = dest;
    while (num && *sour != '\0')
    {
        num--;
        *dest = *sour;
        dest++;
        sour++;
    }
    if (num)
    {
        *dest = '\0';
    }
    return p;
}
int main() {
    char a[10] = "abcdef";  // 目标字符串
    char b[] = "rmn";       // 源字符串
    printf("请输入要拷贝的字符长度: ");

    size_t len;
    if (scanf("%zu", &len) != 1) {  // 使用%zu格式读取size_t类型
        printf("输入错误,程序将退出。\n");
        return 1;
    }

    // 检查请求的长度是否超过目标数组的大小
    if (len > sizeof(a) - 1) {
        printf("请求的长度超过目标数组的大小,无法拷贝。\n");
        return 1;
    }

    // 使用自定义的拷贝函数
    my_strncpy(a, b, len);
    printf("拷贝后的字符串是: %s\n", a);

    return 0;
}
  1. char* my_strncpy(char* dest, const char* sour, int num):定义了一个自定义的字符串拷贝函数my_strncpy,它接受三个参数:目标字符串dest、源字符串sour和要拷贝的字符数量num

  2. char* p = dest;:声明一个字符指针p并初始化为dest的值,用于最后返回拷贝的起始位置。

  3. while (num && *sour != '\0'):使用while循环来拷贝字符,直到num为0或遇到源字符串的结束符'\0'

  4. num--:每次循环时,num减1,表示已经拷贝了一个字符。

  5. *dest = *sour;:将源字符串的当前字符赋值给目标字符串的当前位置。

  6. dest++;sour++;:分别将目标和源字符串的指针向前移动一位。

  7. if (num):如果num不为0,说明已经拷贝完源字符串,但还需要填充剩余的空格。

  8. *dest = '\0';:在目标字符串的末尾添加一个空字符,确保它是以'\0'结尾的字符串。

  9. return p;:返回拷贝的起始位置。

在前面函数总结中有提到一条:如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。我们来调试看一下我们是否实现了这样的效果!

当我们输入要拷贝4个字符时,很显然b[]源字符串的长度是小于4的,我们看到后面的实现效果也确实有在第四个上添置上0。

三、strncat函数说明

函数总结:

  • 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加一个\0字符。
  • 当source长度小于num事,只会将字符串中到\0的内容追加到destination指向的字符串末尾

四、strncat模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest, const char* src, size_t n)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (n--&&*src)
	{
		*dest++ = *src++;
	}
	*dest = '\0';
	return ret;
}
int main()
{
	char a[20] = "Welcome";
	char b[] = " bit 2024";
	size_t len;
	printf("请输入要追加的字符长度");
	scanf("%zu", &len);
	printf("%s", my_strncat(a, b, len));
	return 0;
}

其实这个函数的模拟实现思路很类似于之前的strcat只是限定长度而已。没关系我们还是来逐条代码分析分析。

  1. char* my_strncat(char* dest, const char* src, size_t n):定义了一个自定义的字符串追加函数my_strncat,它接受三个参数:目标字符串dest、源字符串src和要追加的字符数量n

  2. char* ret = dest;:声明一个字符指针ret并初始化为dest的值,用于最后返回追加操作的起始位置。

  3. while (*dest):使用while循环找到目标字符串dest的结尾。

  4. dest++;:将指针dest向前移动到目标字符串的末尾。

  5. while (n--&&*src):使用while循环来追加字符,直到n为0或遇到源字符串的结束符'\0'

  6. *dest++ = *src++;:将源字符串的当前字符赋值给目标字符串的当前位置,并同时将两个指针向前移动一位。

  7. *dest = '\0':在目标字符串的末尾添加一个空字符,确保它是以'\0'结尾的字符串。以防万一,千万不要忘了这一条!

  8. return ret;:返回追加操作的起始位置。

五、strncmp函数说明

函数总结:(这些点在cplusplus中返回值那一项都有提及到)

  • 比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母
  • 如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外一个。
  • 如果num个字符都相等,就返回0

 六、strncmp模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h>

int my_strncmp(const char* s1, const char* s2, size_t n) {
    for (size_t i = 0; i < n; ++i) {
        if (s1[i] != s2[i]) {
            return s1[i] - s2[i]; // 如果当前位置的字符不相等,返回它们的ASCII值差。
        }
    }
    return 0; // 所有比较的字符都相同,或者比较到了n的长度。
}

int main() {
    char s1[] = "hello";
    char s2[] = "helloworld";

    int ret = my_strncmp(s1, s2, 5);

    printf("result = %d\n", ret);

    return 0;
}

 来吧每段代码来剖析一下子

  1. int my_strncmp(const char* s1, const char* s2, size_t n):定义了自定义的字符串比较函数my_strncmp,它接受三个参数:

    • const char* s1:第一个要比较的字符串。
    • const char* s2:第二个要比较的字符串。
    • size_t n:要比较的字符数量。
  2. for (size_t i = 0; i < n; ++i):使用for循环来迭代比较两个字符串中的字符,直到达到指定的字符数量n

  3. if (s1[i] != s2[i]):在循环体内,检查两个字符串在当前索引i处的字符是否相等。

  4. return s1[i] - s2[i];:如果发现两个字符不相等,函数将返回这两个字符的ASCII值之差。这个差值可以用来确定哪个字符串在字典序上是“较小”的。

  5. return 0;:如果循环正常结束,即没有在前n个字符中发现不相等的字符,函数将返回0,表示两个字符串在比较的范围内是相同的。

好啦本节文章就到这里结束啦,如果有什么改进建议可以评论区或者私信我,欢迎各位大佬指正,如果本篇文章对您有帮助的话,三连走一波呗!

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值