Программа Печатает строку неправильно. strcpy - PullRequest
0 голосов
/ 08 мая 2020

После ввода имени и фамилии (пример: name: Mario surname: Rossi) В качестве вывода вместо получения Mario Rossi я получаю ossi Rossi, но не могу понять почему.

int main() {
    char space[] = " ";
    char name[40], surname[40], space_name[40], space_surname[40];
    printf("what's your name");
    scanf("%[^\n]", &name);

    printf("Whats your surname");
    scanf(" %[^\n]", &surname);

    strcpy(space_surname, strcat(space, surname));
    strcat(name, space_surname);
    printf("%s", name);
}

Ответы [ 3 ]

3 голосов
/ 08 мая 2020

В вашем коде вы сначала объединяете surname в конце space с strcat(space, surname), которое имеет неопределенное поведение, поскольку space имеет только 2 элемента, пробел и нулевой терминатор. Копирование surname в конце повреждает массив name, который вы видите, поскольку name становится ossi. Это поведение undefined, это происходит в вашей архитектуре, но поведение undefined может иметь другие последствия, включая отсутствие видимого эффекта или компьютерный треск sh.

Также обратите внимание на эти примечания:

  • вы должны указать scanf() максимальное количество символов для хранения в name и surname, чтобы избежать неопределенного поведения при слишком длинном вводе.
  • вы должны передать name вместо &name.
  • вы должны проверить возвращаемое значение scanf(), чтобы избежать неопределенного поведения при недопустимом вводе, например, в случае неожиданного конца файла или пустой строки для первого scanf().
  • вы можете определить массивы с размерами, которые определяют поведение всегда.

Для более чистого подхода вы должны использовать 2 разных массива firstname и surname для пользовательского ввода и построить имя в третий массив name, достаточно большой для всех случаев:

strcpy(name, firstname);
strcat(name, " ");
strcat(name, surname);

или менее читаемый:

strcat(strcat(strcpy(name, firstname), " "), surname);

Оба вышеперечисленных элемента будут без нужды перебирать символ актеры уже скопированы в name. Более чистым и безопасным решением является использование snprinf():

snprintf(name, sizeof name, "%s %s", firstname, surname);

Вот модифицированная версия:

#include <stdio.h>
#include <string.h>

int main() {
    char firstname[40]; /* up to 39 characters for the first name */
    char surname[40];   /* up to 39 characters for the last name */
    char name[80];      /* 39 chars + 1 space + 39 chars + 1 null terminator */

    printf("What is your name: ");
    if (scanf(" %39[^\n]", name) != 1)
        return 1;

    printf("What is your surname: ");
    if (scanf(" %39[^\n]", surname) != 1)
        return 1;

    /* simpler solution with `snprintf` */
    snprintf(name, sizeof name, "%s %s", firstname, surname);
    printf("%s\n", name);

    return 0;
}
1 голос
/ 08 мая 2020

Для начала эти звонки

scanf("%[^\n]", &name);

scanf(" %[^\n]", &surname);

недействительны. Они должны выглядеть как минимум как

scanf("%[^\n]", name);

scanf(" %[^\n]", surname);

В массиве space недостаточно места для добавления строки, хранящейся в массиве surname. Итак, этот вызов

strcpy(space_surname, strcat(space, surname));

недействителен.

Кажется, вы имеете в виду

strcat( strcpy( space_surname, space ), surname);
1 голос
/ 08 мая 2020

strcat(dest, src) объединит src с dest. Ваш буфер space (длина 1, не включая нулевой терминатор) недостаточно велик, чтобы вместить оба. Кроме того, ваш space_surname будет переполняться, поскольку вы сохраняете строку размера 1 (space) и строку размера 40 (surname) в буфере размера 40. Увеличьте его как минимум до размера 41. Наличие строки space также не обязательно, поскольку space является символом и может быть установлен напрямую.

space_surname[0] = ' ';
space_surname[1] = '\0';  // So you know where to concat to
strcat(space_surname, surname);

Обратите внимание, что вы сталкиваетесь с той же проблемой с name . Вы пытаетесь сохранить name (длина 40), space (длина 1) и surname (длина 40) в name. Вам необходимо создать новую переменную full_name размером 81 или больше и сохранить в ней.

...