Почему эта реализация 'strncpy' работает? - PullRequest
0 голосов
/ 19 февраля 2019

Я должен переписать для назначения функцию, которая имитирует поведение 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.

Мой вопрос:

  • Почему вместо * while или 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);
 }

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

значение i должно быть (n - 1), верно?

Это не обязательно так, поскольку первый цикл while завершается, когда встречается \0символ (даже если i меньше n-1).

Петля while используется для обеспечения правильной инициализации оставшейся части массива dest \0.

«неправильное» поведение, которое вы видите (строка, напечатанная за концом скопированной строки), связано с тем, что оба цикла завершаются с одинаковым условием: первый цикл завершается, когда i становится nи поскольку второй цикл имеет проверку i<n, он не запускается.

Это соответствует поведению, описанному в руководстве:

strncpy () *Функция 1025 * аналогична, за исключением того, что копируется не более n байтов src.Предупреждение: если среди первых n байтов src нет нулевого байта, строка, помещенная в dest, не будет заканчиваться нулем.

Если вы скопировали строкуstr со значением 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;
}
0 голосов
/ 19 февраля 2019

Вы должны понимать, что, хотя они выглядят одинаково, массив 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'.Вам ясно, что происходит в этом примере?

0 голосов
/ 19 февраля 2019

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
...