思想就是 siz 应为 dst_siz,也即先确认好 dst 的内存大小(是内存,也即字符串长度 + 1),这样即使src的长度是比dst大的,也不会超过 dst_siz,可以保证 dst 一直是一个有效的字符串

    如果想用这样函数来拷贝N个字节,那么siz应该为N+1的长度,且N+1 <= 内存长度
    **

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. size_t str_strlcpy(char *dst, const char *src, size_t siz)//其中的siz一般为dst的内存大小
    4. {
    5. char *d = dst;
    6. const char *s = src;
    7. size_t n = siz;
    8. if (n != 0) {
    9. while (--n != 0)//代表dst的内存耗尽了,n==0,进入到下面
    10. if ((*d++ = *s++) == '\0')//代表拷贝完了
    11. break;
    12. }
    13. if (n == 0 ){//判断到n==0,说明dst的内存耗尽了
    14. if (siz != 0)
    15. *d = '\0';//将最后一个字节置位0进行保护,这样dst肯定还能是一个字符串
    16. while (*s++)//将s走到src的尾部,便于下面统计长度
    17. ;
    18. }
    19. return (s - src -1); //仅是统计src的长度,字符个数,也即strlen的长度;如果其等于 siz - 1,那么刚好;如果大于 siz - 1,说明 dst 小了,有没拷贝完的;如果小于 siz - 1,说明dst 够大
    20. }
    21. int main()
    22. {
    23. char test_dst[5] = {0};
    24. const char *a3 = "123";
    25. const char *a4 = "1234";
    26. const char *a5 = "12345";
    27. const char *a6 = "123456";
    28. str_strlcpy(test_dst, a3, 6);
    29. printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
    30. test_dst[0] = '\0';
    31. test_dst[1] = '\0';
    32. test_dst[2] = '\0';
    33. test_dst[3] = '\0';
    34. test_dst[4] = '\0';
    35. str_strlcpy(test_dst, a4, 6);
    36. printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
    37. test_dst[0] = '\0';
    38. test_dst[1] = '\0';
    39. test_dst[2] = '\0';
    40. test_dst[3] = '\0';
    41. test_dst[4] = '\0';
    42. str_strlcpy(test_dst, a5, 6);
    43. printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
    44. test_dst[0] = '\0';
    45. test_dst[1] = '\0';
    46. test_dst[2] = '\0';
    47. test_dst[3] = '\0';
    48. test_dst[4] = '\0';
    49. str_strlcpy(test_dst, a6, 6);
    50. printf("%d.%d.%d.%d.%d\n", test_dst[0], test_dst[1], test_dst[2], test_dst[3], test_dst[4]);
    51. test_dst[0] = '\0';
    52. test_dst[1] = '\0';
    53. test_dst[2] = '\0';
    54. test_dst[3] = '\0';
    55. test_dst[4] = '\0';
    56. return 0;
    57. }