Why does printf behave this way when using struct?When should you use a class vs a struct in C++?Why isn't sizeof for a struct equal to the sum of sizeof of each member?Why are mutable structs “evil”?When to use struct?Why does printf not flush after the call unless a newline is in the format string?Why does the C preprocessor interpret the word “linux” as the constant “1”?Why Choose Struct Over Class?Why does the error struct FILE* but argument is of type char* appear?in a struct, scanf returns var address not valueSegmentation Fault when calling member of a struct

Remove ads in Viber for PC

Can a country avoid prosecution for crimes against humanity by denying it happened?

Calculus Books, preferably Soviet.

Solve this icositetragram

How to check status of Wi-Fi adapter through command line?

What is the maximal acceptable delay between pilot's input and flight control surface actuation?

Given a specific computer system, is it possible to estimate the actual precise run time of a piece of Assembly code

How to add some symbol (or just add newline) if the numbers in the text are not continuous

Why would a Intel 8080 chip be destroyed if +12 V is connected before -5 V?

Initializing a std::array with a constant value

properties that real numbers hold but complex numbers does not

Can an intercepting fighter jet force a small propeller aircraft down without completely destroying it?

Punishment in pacifist society

Why is k-means used for non normally distributed data?

In Toy Story, are toys the only inanimate objects that become alive? And if so, why?

How can I design a magically-induced coma?

Ideal characterization of almost convergence

Meaning of "offen balkon machen"?

Function of the separated, individual solar cells on Telstar 1 and 2? Why were they "special"?

Are manifolds admitting a circle foliation covered by manifolds with a (non-trivial) circle action?

Where is the correct position to set right or left of muscle names for anatomical names?

How to run a command 1 out of N times in Bash

Why are Latin and Sanskrit called dead languages?

When making yogurt, why doesn't bad bacteria grow as well?



Why does printf behave this way when using struct?


When should you use a class vs a struct in C++?Why isn't sizeof for a struct equal to the sum of sizeof of each member?Why are mutable structs “evil”?When to use struct?Why does printf not flush after the call unless a newline is in the format string?Why does the C preprocessor interpret the word “linux” as the constant “1”?Why Choose Struct Over Class?Why does the error struct FILE* but argument is of type char* appear?in a struct, scanf returns var address not valueSegmentation Fault when calling member of a struct






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0















I am writing a code while making the use of structures. I am new to structs so I am practicing to get used to it. Anyway while trying to use printf on a variable of type string which is a variable of a struct type, printf only prints '@' instead of the whole string.



...

void signPlayers(struct player players[9], int playersC) // players is an array declared on main and playersC is the size of it.

for (int i = 0; i < playersC; i++)

char tname[22];
printf("Please enter the name of the player #%d: n",i+1);
int res = scanf(" %s",&tname);
while(res != 1)

printf("Please enter a valid name for player #%d: n",i+1);
res = scanf(" %s",&tname);

players[i].name = tname;
printf("Player #%d signed as %s!nn",players[i].id,players[i].name); // this printf actually works fine



int checkForWinner(struct player players[], int playersC)

for (int i = 0; i < playersC; i++)

if (players[i].pos == 10)
return 0;
printf("%sn",players[i].name); // prints "@" instead of the name

return 1;


...


so If I entered the name Joey, At first printf it actually prints "Joey", then when I call the checkForWinner function (Its called after signPlayers function), the printf now prints only "@" instead of the whole name again.
What could be wrong?










share|improve this question



















  • 3





    Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

    – paddy
    Mar 28 at 1:50











  • Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

    – Ameer Shehadey
    Mar 28 at 1:56







  • 2





    @AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

    – Mike Holt
    Mar 28 at 2:19











  • Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

    – Ameer Shehadey
    Mar 28 at 2:19











  • Also scanf(" %s",&tname); --> scanf("%21s",tname);

    – chux
    Mar 28 at 2:20

















0















I am writing a code while making the use of structures. I am new to structs so I am practicing to get used to it. Anyway while trying to use printf on a variable of type string which is a variable of a struct type, printf only prints '@' instead of the whole string.



...

void signPlayers(struct player players[9], int playersC) // players is an array declared on main and playersC is the size of it.

for (int i = 0; i < playersC; i++)

char tname[22];
printf("Please enter the name of the player #%d: n",i+1);
int res = scanf(" %s",&tname);
while(res != 1)

printf("Please enter a valid name for player #%d: n",i+1);
res = scanf(" %s",&tname);

players[i].name = tname;
printf("Player #%d signed as %s!nn",players[i].id,players[i].name); // this printf actually works fine



int checkForWinner(struct player players[], int playersC)

for (int i = 0; i < playersC; i++)

if (players[i].pos == 10)
return 0;
printf("%sn",players[i].name); // prints "@" instead of the name

return 1;


...


so If I entered the name Joey, At first printf it actually prints "Joey", then when I call the checkForWinner function (Its called after signPlayers function), the printf now prints only "@" instead of the whole name again.
What could be wrong?










share|improve this question



















  • 3





    Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

    – paddy
    Mar 28 at 1:50











  • Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

    – Ameer Shehadey
    Mar 28 at 1:56







  • 2





    @AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

    – Mike Holt
    Mar 28 at 2:19











  • Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

    – Ameer Shehadey
    Mar 28 at 2:19











  • Also scanf(" %s",&tname); --> scanf("%21s",tname);

    – chux
    Mar 28 at 2:20













0












0








0








I am writing a code while making the use of structures. I am new to structs so I am practicing to get used to it. Anyway while trying to use printf on a variable of type string which is a variable of a struct type, printf only prints '@' instead of the whole string.



...

void signPlayers(struct player players[9], int playersC) // players is an array declared on main and playersC is the size of it.

for (int i = 0; i < playersC; i++)

char tname[22];
printf("Please enter the name of the player #%d: n",i+1);
int res = scanf(" %s",&tname);
while(res != 1)

printf("Please enter a valid name for player #%d: n",i+1);
res = scanf(" %s",&tname);

players[i].name = tname;
printf("Player #%d signed as %s!nn",players[i].id,players[i].name); // this printf actually works fine



int checkForWinner(struct player players[], int playersC)

for (int i = 0; i < playersC; i++)

if (players[i].pos == 10)
return 0;
printf("%sn",players[i].name); // prints "@" instead of the name

return 1;


...


so If I entered the name Joey, At first printf it actually prints "Joey", then when I call the checkForWinner function (Its called after signPlayers function), the printf now prints only "@" instead of the whole name again.
What could be wrong?










share|improve this question














I am writing a code while making the use of structures. I am new to structs so I am practicing to get used to it. Anyway while trying to use printf on a variable of type string which is a variable of a struct type, printf only prints '@' instead of the whole string.



...

void signPlayers(struct player players[9], int playersC) // players is an array declared on main and playersC is the size of it.

for (int i = 0; i < playersC; i++)

char tname[22];
printf("Please enter the name of the player #%d: n",i+1);
int res = scanf(" %s",&tname);
while(res != 1)

printf("Please enter a valid name for player #%d: n",i+1);
res = scanf(" %s",&tname);

players[i].name = tname;
printf("Player #%d signed as %s!nn",players[i].id,players[i].name); // this printf actually works fine



int checkForWinner(struct player players[], int playersC)

for (int i = 0; i < playersC; i++)

if (players[i].pos == 10)
return 0;
printf("%sn",players[i].name); // prints "@" instead of the name

return 1;


...


so If I entered the name Joey, At first printf it actually prints "Joey", then when I call the checkForWinner function (Its called after signPlayers function), the printf now prints only "@" instead of the whole name again.
What could be wrong?







c struct






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 28 at 1:46









Ameer ShehadeyAmeer Shehadey

83 bronze badges




83 bronze badges










  • 3





    Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

    – paddy
    Mar 28 at 1:50











  • Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

    – Ameer Shehadey
    Mar 28 at 1:56







  • 2





    @AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

    – Mike Holt
    Mar 28 at 2:19











  • Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

    – Ameer Shehadey
    Mar 28 at 2:19











  • Also scanf(" %s",&tname); --> scanf("%21s",tname);

    – chux
    Mar 28 at 2:20












  • 3





    Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

    – paddy
    Mar 28 at 1:50











  • Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

    – Ameer Shehadey
    Mar 28 at 1:56







  • 2





    @AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

    – Mike Holt
    Mar 28 at 2:19











  • Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

    – Ameer Shehadey
    Mar 28 at 2:19











  • Also scanf(" %s",&tname); --> scanf("%21s",tname);

    – chux
    Mar 28 at 2:20







3




3





Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

– paddy
Mar 28 at 1:50





Your program has undefined behavior because you store a pointer to memory on the stack and then try to use it after that stack has gone out of scope.

– paddy
Mar 28 at 1:50













Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

– Ameer Shehadey
Mar 28 at 1:56






Wait I didn't get it, so what pointer did you talk about and when or why did the stack go out of scope? If I may ask. @paddy

– Ameer Shehadey
Mar 28 at 1:56





2




2





@AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

– Mike Holt
Mar 28 at 2:19





@AmeerShehadey The assignment players[i].name = tname is assigning the address of a char array that exists only on the stack, and only for the duration of the call to signPlayers. You're then attempting to print the contents of that array, but tname went out of scope when the call to signPlayers completed, and now the memory that players[i].name is pointing to is just whatever random garbage was left over afterwards.

– Mike Holt
Mar 28 at 2:19













Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

– Ameer Shehadey
Mar 28 at 2:19





Okay, I think problem is solved after using the name member on the player struct as char name[] instead of char* name.

– Ameer Shehadey
Mar 28 at 2:19













Also scanf(" %s",&tname); --> scanf("%21s",tname);

– chux
Mar 28 at 2:20





Also scanf(" %s",&tname); --> scanf("%21s",tname);

– chux
Mar 28 at 2:20












1 Answer
1






active

oldest

votes


















1















Your code is attempting to access stack memory after the function has returned. When you do that, you get just whatever garbage was left over after the function call, or perhaps some part of a new stack frame belonging to a different function. Either way, it's undefined behavior.



There are several problems with the assignment players[i].name = tname; in function signPlayers:



  1. It is assigning the address of the local array variable tname. This variable goes out of scope on every iteration through the loop. That means accessing that pointer after the loop will be undefined behavior.


  2. Even if tname was moved out of the loop's scope up to the function scope, it will still go out of scope as soon as the function returns. Either way, accessing it after the function call is undefined behavior.


  3. It's likely that the address of tname doesn't change from one iteration of the loop to the next. So that means that the .name member of every player in the players array will probably be identical (as well as being invalid).


There are many ways to fix this. Here are three ways:




  1. Make a copy of tname each time through the loop using strdup(tname), and assign that to players[i].name:



    players[i].name = strdup(tname);


    The strdup function allocates memory, so if you use this approach, you will need to remember to free the .name member of each player when you're done.




  2. Allocate memory dynamically to each players[i].name prior to calling signPlayers:



    for (i=0; i<playersC; ++i) players[i].name = malloc(22);
    signPlayers(players, playersC);
    // Don't forget to call free() on each .name member after you're done


    Inside signPlayers, you would then get rid of tname altogether and do:



    int res = scanf(" %s", players[i].name);


    Note: No need to do 22 * sizeof(char) here, since the C standard guarantees sizeof(char) == 1. Also, I used 22 because that's what OP's code uses to declare tname. However, it should be noted that scanf is less than ideal here, because it gives no way to limit the number of bytes written to the array, and thus no way to protect against buffer overflow. If you type a name longer than 21 characters (need to leave 1 byte for the null terminator), then you will overflow tname and your program will either crash or silently corrupt your data.




  3. Turn players[i].name into a sized char array instead of just a char pointer. In other words, statically allocate memory to each players[i].name. This has the advantage of not needing to call free, as you would need to do with methods 1 and 2. OP didn't show the definition of struct player, but this should suffice for example purposes:



    struct player 
    char name[22];
    // other stuff
    ;


    And again, inside signPlayers, you would scanf directly into players[i].name instead of using tname.







share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388988%2fwhy-does-printf-behave-this-way-when-using-struct%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1















    Your code is attempting to access stack memory after the function has returned. When you do that, you get just whatever garbage was left over after the function call, or perhaps some part of a new stack frame belonging to a different function. Either way, it's undefined behavior.



    There are several problems with the assignment players[i].name = tname; in function signPlayers:



    1. It is assigning the address of the local array variable tname. This variable goes out of scope on every iteration through the loop. That means accessing that pointer after the loop will be undefined behavior.


    2. Even if tname was moved out of the loop's scope up to the function scope, it will still go out of scope as soon as the function returns. Either way, accessing it after the function call is undefined behavior.


    3. It's likely that the address of tname doesn't change from one iteration of the loop to the next. So that means that the .name member of every player in the players array will probably be identical (as well as being invalid).


    There are many ways to fix this. Here are three ways:




    1. Make a copy of tname each time through the loop using strdup(tname), and assign that to players[i].name:



      players[i].name = strdup(tname);


      The strdup function allocates memory, so if you use this approach, you will need to remember to free the .name member of each player when you're done.




    2. Allocate memory dynamically to each players[i].name prior to calling signPlayers:



      for (i=0; i<playersC; ++i) players[i].name = malloc(22);
      signPlayers(players, playersC);
      // Don't forget to call free() on each .name member after you're done


      Inside signPlayers, you would then get rid of tname altogether and do:



      int res = scanf(" %s", players[i].name);


      Note: No need to do 22 * sizeof(char) here, since the C standard guarantees sizeof(char) == 1. Also, I used 22 because that's what OP's code uses to declare tname. However, it should be noted that scanf is less than ideal here, because it gives no way to limit the number of bytes written to the array, and thus no way to protect against buffer overflow. If you type a name longer than 21 characters (need to leave 1 byte for the null terminator), then you will overflow tname and your program will either crash or silently corrupt your data.




    3. Turn players[i].name into a sized char array instead of just a char pointer. In other words, statically allocate memory to each players[i].name. This has the advantage of not needing to call free, as you would need to do with methods 1 and 2. OP didn't show the definition of struct player, but this should suffice for example purposes:



      struct player 
      char name[22];
      // other stuff
      ;


      And again, inside signPlayers, you would scanf directly into players[i].name instead of using tname.







    share|improve this answer































      1















      Your code is attempting to access stack memory after the function has returned. When you do that, you get just whatever garbage was left over after the function call, or perhaps some part of a new stack frame belonging to a different function. Either way, it's undefined behavior.



      There are several problems with the assignment players[i].name = tname; in function signPlayers:



      1. It is assigning the address of the local array variable tname. This variable goes out of scope on every iteration through the loop. That means accessing that pointer after the loop will be undefined behavior.


      2. Even if tname was moved out of the loop's scope up to the function scope, it will still go out of scope as soon as the function returns. Either way, accessing it after the function call is undefined behavior.


      3. It's likely that the address of tname doesn't change from one iteration of the loop to the next. So that means that the .name member of every player in the players array will probably be identical (as well as being invalid).


      There are many ways to fix this. Here are three ways:




      1. Make a copy of tname each time through the loop using strdup(tname), and assign that to players[i].name:



        players[i].name = strdup(tname);


        The strdup function allocates memory, so if you use this approach, you will need to remember to free the .name member of each player when you're done.




      2. Allocate memory dynamically to each players[i].name prior to calling signPlayers:



        for (i=0; i<playersC; ++i) players[i].name = malloc(22);
        signPlayers(players, playersC);
        // Don't forget to call free() on each .name member after you're done


        Inside signPlayers, you would then get rid of tname altogether and do:



        int res = scanf(" %s", players[i].name);


        Note: No need to do 22 * sizeof(char) here, since the C standard guarantees sizeof(char) == 1. Also, I used 22 because that's what OP's code uses to declare tname. However, it should be noted that scanf is less than ideal here, because it gives no way to limit the number of bytes written to the array, and thus no way to protect against buffer overflow. If you type a name longer than 21 characters (need to leave 1 byte for the null terminator), then you will overflow tname and your program will either crash or silently corrupt your data.




      3. Turn players[i].name into a sized char array instead of just a char pointer. In other words, statically allocate memory to each players[i].name. This has the advantage of not needing to call free, as you would need to do with methods 1 and 2. OP didn't show the definition of struct player, but this should suffice for example purposes:



        struct player 
        char name[22];
        // other stuff
        ;


        And again, inside signPlayers, you would scanf directly into players[i].name instead of using tname.







      share|improve this answer





























        1














        1










        1









        Your code is attempting to access stack memory after the function has returned. When you do that, you get just whatever garbage was left over after the function call, or perhaps some part of a new stack frame belonging to a different function. Either way, it's undefined behavior.



        There are several problems with the assignment players[i].name = tname; in function signPlayers:



        1. It is assigning the address of the local array variable tname. This variable goes out of scope on every iteration through the loop. That means accessing that pointer after the loop will be undefined behavior.


        2. Even if tname was moved out of the loop's scope up to the function scope, it will still go out of scope as soon as the function returns. Either way, accessing it after the function call is undefined behavior.


        3. It's likely that the address of tname doesn't change from one iteration of the loop to the next. So that means that the .name member of every player in the players array will probably be identical (as well as being invalid).


        There are many ways to fix this. Here are three ways:




        1. Make a copy of tname each time through the loop using strdup(tname), and assign that to players[i].name:



          players[i].name = strdup(tname);


          The strdup function allocates memory, so if you use this approach, you will need to remember to free the .name member of each player when you're done.




        2. Allocate memory dynamically to each players[i].name prior to calling signPlayers:



          for (i=0; i<playersC; ++i) players[i].name = malloc(22);
          signPlayers(players, playersC);
          // Don't forget to call free() on each .name member after you're done


          Inside signPlayers, you would then get rid of tname altogether and do:



          int res = scanf(" %s", players[i].name);


          Note: No need to do 22 * sizeof(char) here, since the C standard guarantees sizeof(char) == 1. Also, I used 22 because that's what OP's code uses to declare tname. However, it should be noted that scanf is less than ideal here, because it gives no way to limit the number of bytes written to the array, and thus no way to protect against buffer overflow. If you type a name longer than 21 characters (need to leave 1 byte for the null terminator), then you will overflow tname and your program will either crash or silently corrupt your data.




        3. Turn players[i].name into a sized char array instead of just a char pointer. In other words, statically allocate memory to each players[i].name. This has the advantage of not needing to call free, as you would need to do with methods 1 and 2. OP didn't show the definition of struct player, but this should suffice for example purposes:



          struct player 
          char name[22];
          // other stuff
          ;


          And again, inside signPlayers, you would scanf directly into players[i].name instead of using tname.







        share|improve this answer















        Your code is attempting to access stack memory after the function has returned. When you do that, you get just whatever garbage was left over after the function call, or perhaps some part of a new stack frame belonging to a different function. Either way, it's undefined behavior.



        There are several problems with the assignment players[i].name = tname; in function signPlayers:



        1. It is assigning the address of the local array variable tname. This variable goes out of scope on every iteration through the loop. That means accessing that pointer after the loop will be undefined behavior.


        2. Even if tname was moved out of the loop's scope up to the function scope, it will still go out of scope as soon as the function returns. Either way, accessing it after the function call is undefined behavior.


        3. It's likely that the address of tname doesn't change from one iteration of the loop to the next. So that means that the .name member of every player in the players array will probably be identical (as well as being invalid).


        There are many ways to fix this. Here are three ways:




        1. Make a copy of tname each time through the loop using strdup(tname), and assign that to players[i].name:



          players[i].name = strdup(tname);


          The strdup function allocates memory, so if you use this approach, you will need to remember to free the .name member of each player when you're done.




        2. Allocate memory dynamically to each players[i].name prior to calling signPlayers:



          for (i=0; i<playersC; ++i) players[i].name = malloc(22);
          signPlayers(players, playersC);
          // Don't forget to call free() on each .name member after you're done


          Inside signPlayers, you would then get rid of tname altogether and do:



          int res = scanf(" %s", players[i].name);


          Note: No need to do 22 * sizeof(char) here, since the C standard guarantees sizeof(char) == 1. Also, I used 22 because that's what OP's code uses to declare tname. However, it should be noted that scanf is less than ideal here, because it gives no way to limit the number of bytes written to the array, and thus no way to protect against buffer overflow. If you type a name longer than 21 characters (need to leave 1 byte for the null terminator), then you will overflow tname and your program will either crash or silently corrupt your data.




        3. Turn players[i].name into a sized char array instead of just a char pointer. In other words, statically allocate memory to each players[i].name. This has the advantage of not needing to call free, as you would need to do with methods 1 and 2. OP didn't show the definition of struct player, but this should suffice for example purposes:



          struct player 
          char name[22];
          // other stuff
          ;


          And again, inside signPlayers, you would scanf directly into players[i].name instead of using tname.








        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 28 at 8:21

























        answered Mar 28 at 8:16









        Mike HoltMike Holt

        3,5891 gold badge10 silver badges22 bronze badges




        3,5891 gold badge10 silver badges22 bronze badges





















            Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







            Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388988%2fwhy-does-printf-behave-this-way-when-using-struct%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript