Leit22
Leit22

Reputation: 13

Program Prints the string in the wrong way. strcpy

After I put the input for name and surname (example: name:Mario surname:Rossi) As an output instead of getting Mario Rossi I get ossi Rossi but I can't understand why.

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);
}

Upvotes: 0

Views: 117

Answers (3)

chqrlie
chqrlie

Reputation: 144550

In your code, you first concatenate surname at the end of space with strcat(space, surname), which has undefined behavior as space only has 2 elements, a space and a null terminator. Copying surname at the end corrupts the array name, which you observe as the name becomes ossi. This behavior is undefined, it happens this way on your architecture, but undefined behavior could have other consequences, including no visible effect or a computer crash.

Also note these remarks:

  • you should tell scanf() the maximum number of characters to store into name and surname to avoid undefined behavior on overlong input.
  • you should pass name instead of &name.
  • you should test the return value of scanf() to avoid undefined behavior on invalid input, for example in case of unexpected end of file or an empty line for the first scanf().
  • you could define the arrays with sizes that make the behavior always defined.

For a cleaner approach, you would use 2 different arrays firstname and surname for the user input and construct the name into a third array name large enough for all cases:

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

or less readably:

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

Both of the above would needlessly iterate over the characters already copied into name. A much cleaner and safer solution is to use snprinf():

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

Here is a modified version:

#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;
}

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 310920

For starters these calls

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

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

are invalid. They must look at least like

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

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

The array space has no enough space to append the string stored in the array surname. So this call

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

is invalid.

It seems you mean

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

Upvotes: 1

Michael Bianconi
Michael Bianconi

Reputation: 5232

strcat(dest, src) will concatenate src onto dest. Your buffer space (length 1 not including null-terminator) isn't large enough to hold both. Also, your space_surname will overflow, as you're storing a size 1 string (space) and a size 40 string (surname) into a size 40 buffer. Increase it to at least size 41. Having a space string is also unnecessary, as space is character and can be set directly.

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

Note you run into the same issue with name. You're trying to store name (length 40), space (length 1), and surname(length 40) all into name. You need to create a new full_name variable of size 81 or greater and store into that.

Upvotes: 1

Related Questions