0

经过多次试验和错误,一些外部帮助后,我必须为分配重写一个模仿 strncpy 行为的函数,这是最终代码:

 15 char    *ft_strncpy(char *dest, char *src, unsigned int n)
 16 {
 17     unsigned int i;
 18     unsigned int size;
 19
 20     i = 0;
 21     size = 0;
 22     while (src[i] && i < n)
 23     {
 24         dest[i] = src[i];
 25         i++;
 26     }
 27     while (i < n)
 28     {
 29         dest[i] = '\0';
 30         i++;
 31     }
 32     return (dest);
 33 }

它完美无缺,但我不明白这部分:

 while (i < n)
 {
     dest[i] = '\0';
     i++;
 }

此时, i 的值应该是 (n - 1) 对吧?所以'\0' goes into dest[n-1]循环结束,因为i becomes equal to n然后函数结束。

我们留下了一个看起来像这样的字符串:

"string copied\0not copied part"

并打印为 : string copiednot copied part

我的问题是:

  • 当他们基本上做同样的事情时,为什么dest[n-1]='\0'或者dest[n]='\0'而不是那个while循环,string copied而不是'字符串复制而不复制部分'返回?

  • 为什么\0在 while 循环之后打印出来时似乎被“忽略”,而当我使用 dest[n-1] = '\0' 时它被认为是句号?

这是我用来运行测试并尝试理解的主要/替代功能:

int main()
{
     char str[] = "test de chaine";
     char *str2 = "chaine de test";

     ft_strncpy(str, str2, 6);
     printf("%s", str);
     return 0;
}

char    *ft_strncpy(char *dest, char *src, unsigned int n)
 {
     unsigned int i;
     unsigned int size;

     i = 0;
     size = 0;
     while (src[i] && i < n)
     {
         dest[i] = src[i];
         i++;
     }
         dest[n-1] = '\0';
     return (dest);
 }
4

3 回答 3

1

strncpy()被指定为精确写入n字节,与源字符串的长度无关。

strncpy(dst, "foo", 5); // writes 'f', 'o', 'o', 0, and 0
strncpy(dst, "foo", 3); // writes 'f', 'o', and 'o': dst is not a string now (*)
strncpy(dst, "foo", 1); // write 'f': dst is not a string now (*)
// (*) unless you make sure there is a '\0' somewhere else in dst
于 2019-02-19T16:41:19.237 回答
1

i 的值应该是 (n - 1) 对吗?

不一定是这种情况,因为第一个while循环在遇到\0字符时退出(即使i小于n-1)。

while-loop 用于确保数组的其余部分正确dest初始化为\0.

您看到的“错误”行为(在复制的字符串末尾打印的字符串)是由于两个循环以相同的条件退出:第一个循环在i变为时退出,n并且由于第二个循环有 check i<n,它不运行。

这对应于手册中描述的行为:

strncpy()函数是类似的,除了最多复制n的字节。警告:如果 的第一个字节中src没有空字节,则放入的字符串不会以空结尾。nsrcdest

如果要复制str带有 value的字符串abc,它将在下面的示例中正确显示:

#include <stdio.h>

char    *ft_strncpy(char *dest, char *src, unsigned int n)
{
    unsigned int i;
    unsigned int size;

    i = 0;
    size = 0;
    while (src[i] && i < n)
    {
        dest[i] = src[i];
        i++;
    }
    while (i < n)
    {
        dest[i] = '\0';
        i++;
    }
    return (dest);
}

int main()
{
     char str[] = "test de chaine";
     char *str2 = "abc";

     ft_strncpy(str, str2, 6);
     printf("%s\n", str);
     return 0;
}
于 2019-02-19T16:41:52.113 回答
0

您需要了解,虽然它们看起来相似,但 char 数组不是字符串,而字符串是 char 数组。某些函数(即 string.h 函数)会一个接一个地读取每个字节,并在遇到 '\ 0'。所以检查这个例子,你会有不同的看法。

int main()
{
     char str3[] = "This is a test";

     printf("\n %s", str3);
     str3[5] = '\0';
     printf("\n %s \n", str3);
     int i = 0;
     for(i = 0 ; i < strlen(str3) ; i ++)
     {
         printf(" %c -",str3[i] );
     }
     printf("\n");
     for(i = 0 ; i < 12 ; i ++)
     {
         printf(" %c -",str3[i] );
     }
     return 0;
}

我们打印的不是我们在内存中的内容。特别是使用 %s 将流式传输 char 数组并在命中 '\0' 时停止。你清楚这个例子中发生的事情吗?

于 2019-02-19T17:05:56.637 回答