正文开始@边通书
:apple:上篇文章介绍了没有长度限制的几个字符串库函数strcpy
,strcat
,strcmp
,它们就是上来就是干,直至\0为止,是不太安全的。
本文将继续介绍相对安全的几个有长度限制的字符串库函strncpy
,strncat
,strncmp
及其 模拟实现。这些模拟实现都是我凭借:snowflake:颤抖直觉:snowflake:写出来的,当然不完美,同时也可以去参考一下标准库函数,小边看的时候真是大喊妙绝,但对于新手不建议追求奇淫技巧,以逻辑和可读性为主。
4.strncpy
想要很好的模拟实现原逻辑,要先充分了解函数的脾气。
:innocent:strncpy
的模拟实现---my_strncpy
#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest, const char* src, size_t count)
{
assert(dest&&src);//断言--保证指针有效性
size_t i = 0;
char* ret = dest;
for (i = 0; i < count; i++)
{
*(dest + i) = *(src + i);//拷贝
//若count>字符串内容
if (*(src + i) == '\0')
{
for (i += 1; i < count; i++)
{
*(dest + i) = 0;
}
}
}
return ret;
}
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "xxxx";
char* ret = my_strncpy(arr1, arr2, 6);
printf("%s\n", ret);
return 0;
}
运行结果:
标准库函数:
5.strncat
想要很好的模拟实现原逻辑,要先充分了解函数的脾气。
:innocent:strncat
的模拟实现---my_strncat
#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest, const char* src, size_t num)
{
assert(dest&&src);
size_t i = 0;
char* ret = dest;
//1.找到\0位置
while (*dest)
{
dest++;
}
//2.追加
for (i = 0; i < num; i++)
{
if (*(src + i) == '\0')
{
break;
}
*(dest + i) = *(src + i);
}
*(dest + i) = '\0';//主动添加\0
return ret;
}
int main()
{
char arr1[] = "abc\0xxxxxxxxxx";
char arr2[] = "def";
my_strncat(arr1, arr2, 6);
return 0;
}
运行结果:
参考标准库函数:
6.strncmp
想要很好的模拟实现原逻辑,要先充分了解函数的脾气。
:innocent:strncmp
的模拟实现---my_strncmp
#include<stdio.h>
#include<assert.h>
int strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1&&str2);
size_t i = 0;
while (*str1 == *str2)//字符相同
{
i++;
//若遇到\0或已到num仍相同,则返回0
if ((*str1 == '\0') ||(i==num) )
{
return 0;
}
str1++;
str2++;
}
//若字符不同,则返回差值
return *str1 - *str2;
}
int main()
{
char arr1[] = "abcwef";
char arr2[] = "ab";
int ret = strncmp(arr1, arr2, 3);
printf("%d\n", ret);
return 0;
}
运行结果:
未完待续
:star:下篇文章将继续介绍strstr
,strtok
,strerrot
这些字符串库函数以及字符操作