前言:
这篇文章我们将会讲到三个库函数的模拟实现,前面文章所讲到的strcpy、strcat、strcmp他们为长度不受限制的字符串函数,而今天要讲到的是长度受限制的字符串函数,因为前面函数的铺垫这次我们三个函数一起讲完。新朋友可以点击链接观看一下之前的库函数模拟实现内容strncpy、strcat、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;
}
-
char* my_strncpy(char* dest, const char* sour, int num)
:定义了一个自定义的字符串拷贝函数my_strncpy
,它接受三个参数:目标字符串dest
、源字符串sour
和要拷贝的字符数量num
。 -
char* p = dest;
:声明一个字符指针p
并初始化为dest
的值,用于最后返回拷贝的起始位置。 -
while (num && *sour != '\0')
:使用while
循环来拷贝字符,直到num
为0或遇到源字符串的结束符'\0'
。 -
num--
:每次循环时,num
减1,表示已经拷贝了一个字符。 -
*dest = *sour;
:将源字符串的当前字符赋值给目标字符串的当前位置。 -
dest++;
和sour++;
:分别将目标和源字符串的指针向前移动一位。 -
if (num)
:如果num
不为0,说明已经拷贝完源字符串,但还需要填充剩余的空格。 -
*dest = '\0';
:在目标字符串的末尾添加一个空字符,确保它是以'\0'
结尾的字符串。 -
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只是限定长度而已。没关系我们还是来逐条代码分析分析。
-
char* my_strncat(char* dest, const char* src, size_t n)
:定义了一个自定义的字符串追加函数my_strncat
,它接受三个参数:目标字符串dest
、源字符串src
和要追加的字符数量n
。 -
char* ret = dest;
:声明一个字符指针ret
并初始化为dest
的值,用于最后返回追加操作的起始位置。 -
while (*dest)
:使用while
循环找到目标字符串dest
的结尾。 -
dest++;
:将指针dest
向前移动到目标字符串的末尾。 -
while (n--&&*src)
:使用while
循环来追加字符,直到n
为0或遇到源字符串的结束符'\0'
。 -
*dest++ = *src++;
:将源字符串的当前字符赋值给目标字符串的当前位置,并同时将两个指针向前移动一位。 -
*dest = '\0'
:在目标字符串的末尾添加一个空字符,确保它是以'\0'
结尾的字符串。以防万一,千万不要忘了这一条! -
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;
}
来吧每段代码来剖析一下子
-
int my_strncmp(const char* s1, const char* s2, size_t n)
:定义了自定义的字符串比较函数my_strncmp
,它接受三个参数:const char* s1
:第一个要比较的字符串。const char* s2
:第二个要比较的字符串。size_t n
:要比较的字符数量。
-
for (size_t i = 0; i < n; ++i)
:使用for
循环来迭代比较两个字符串中的字符,直到达到指定的字符数量n
。 -
if (s1[i] != s2[i])
:在循环体内,检查两个字符串在当前索引i
处的字符是否相等。 -
return s1[i] - s2[i];
:如果发现两个字符不相等,函数将返回这两个字符的ASCII值之差。这个差值可以用来确定哪个字符串在字典序上是“较小”的。 -
return 0;
:如果循环正常结束,即没有在前n
个字符中发现不相等的字符,函数将返回0
,表示两个字符串在比较的范围内是相同的。
好啦本节文章就到这里结束啦,如果有什么改进建议可以评论区或者私信我,欢迎各位大佬指正,如果本篇文章对您有帮助的话,三连走一波呗!