思想就是 siz 应为 dst_siz,也即先确认好 dst 的内存大小(是内存,也即字符串长度 + 1),这样即使src的长度是比dst大的,也不会超过 dst_siz,可以保证 dst 一直是一个有效的字符串
如果想用这样函数来拷贝N个字节,那么siz应该为N+1的长度,且N+1 <= 内存长度
**
#include <stdio.h>
#include <stdlib.h>
size_t str_strlcpy(char *dst, const char *src, size_t siz)//其中的siz一般为dst的内存大小
{
char *d = dst;
const char *s = src;
size_t n = siz;
if (n != 0) {
while (--n != 0)//代表dst的内存耗尽了,n==0,进入到下面
if ((*d++ = *s++) == '\0')//代表拷贝完了
break;
}
if (n == 0 ){//判断到n==0,说明dst的内存耗尽了
if (siz != 0)
*d = '\0';//将最后一个字节置位0进行保护,这样dst肯定还能是一个字符串
while (*s++)//将s走到src的尾部,便于下面统计长度
;
}
return (s - src -1); //仅是统计src的长度,字符个数,也即strlen的长度;如果其等于 siz - 1,那么刚好;如果大于 siz - 1,说明 dst 小了,有没拷贝完的;如果小于 siz - 1,说明dst 够大
}
int main()
{
char test_dst[5] = {0};
const char *a3 = "123";
const char *a4 = "1234";
const char *a5 = "12345";
const char *a6 = "123456";
str_strlcpy(test_dst, a3, 6);
printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
test_dst[0] = '\0';
test_dst[1] = '\0';
test_dst[2] = '\0';
test_dst[3] = '\0';
test_dst[4] = '\0';
str_strlcpy(test_dst, a4, 6);
printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
test_dst[0] = '\0';
test_dst[1] = '\0';
test_dst[2] = '\0';
test_dst[3] = '\0';
test_dst[4] = '\0';
str_strlcpy(test_dst, a5, 6);
printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
test_dst[0] = '\0';
test_dst[1] = '\0';
test_dst[2] = '\0';
test_dst[3] = '\0';
test_dst[4] = '\0';
str_strlcpy(test_dst, a6, 6);
printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
test_dst[0] = '\0';
test_dst[1] = '\0';
test_dst[2] = '\0';
test_dst[3] = '\0';
test_dst[4] = '\0';
return 0;
}