Sirop4ik
Sirop4ik

Reputation: 5233

How to write char[] into struct?

I have such struct names

#define SETA_NAME "SETA"
#define SETB_NAME "SETB"
#define SETC_NAME "SETC"
#define SETD_NAME "SETD"
#define SETE_NAME "SETE"
#define SETF_NAME "SETF"

Such struct

struct set
{
    char name[SET_NAME_LENGTH + 1];
    unsigned int input[INPUT_ARR_SIZE];
};

typedef struct set SETA, SETB, SETC, SETD, SETE, SETF;

And here is code that I try to execute

    SETA setA;
    memcpy(setA.name, SETA_NAME, sizeof(SETA_NAME));
    SETB setB;
    memcpy(setA.name, SETB_NAME, sizeof(SETB_NAME));
    SETC setC;
    memcpy(setA.name, SETC_NAME, sizeof(SETC_NAME));
    SETD setD;
    memcpy(setA.name, SETD_NAME, sizeof(SETD_NAME));
    SETE setE;
    memcpy(setA.name, SETE_NAME, sizeof(SETE_NAME));
    SETF setF;
    memcpy(setA.name, SETF_NAME, sizeof(SETF_NAME));

    printf("\nNAME : %s", setA.name);
    printf("\nNAME : %s", setB.name);
    printf("\nNAME : %s", setC.name);
    printf("\nNAME : %s", setD.name);
    printf("\nNAME : %s", setE.name);
    printf("\nNAME : %s", setF.name);

But output not as I expect

NAME : SETF
NAME : 
NAME : 
NAME : 
NAME : d?v
NAME : 

What I am doing wrong?

Upvotes: 0

Views: 70

Answers (2)

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16017

You may be interested in initializing structs. In C (and, in a widely enhanced fashion, in C++) structs can be initialized with a list of values in curly braces. Each value stands for a member; missing members at the end are initialized with 0 (which implies that an empty pair of curly braces initializes every member with 0).

For character arrays it's possible to use character string literals for initialization, so you could take your predefined strings as initializers. I have written a little test program for demonstration. Enjoy.

#include<stdio.h>

// give the array a reasonable size.
#define SET_NAME_LENGTH 80
#define INPUT_ARR_SIZE 4

#define SETA_NAME "SETA"
#define SETB_NAME "SETB"
#define SETC_NAME "SETC"
#define SETD_NAME "SETD"


struct set
{
    char name[SET_NAME_LENGTH + 1];
    unsigned int input[INPUT_ARR_SIZE];
};

// 
// why? 
// typedef struct set  SETA, SETB, SETC, SETD, SETE, SETF;


int main() 
{
  // The first improvement: Do value initialization.
  // Each name array is initialized with the characters from the
  // supplied character string literal.
  // All integers in the int array are initialized with 0 in all structs below:
  struct set setA = { SETA_NAME, {0,0,0,0} }; // verbose
  struct set setB = { SETB_NAME, {0} };       // less verbose: omitted members are zeroed.
  struct set setC = { SETC_NAME, {} };        // even less verbose: omitted members are zeroed.
  struct set setD = { SETD_NAME     };        // terse: omitted members are zeroed recursively.

  struct set empty = {}; // Convenient way to zero out everything.

  printf("\nNAME : %s", setA.name);
  printf("\nNAME : %s", setB.name);
  printf("\nNAME : %s", setC.name);
  printf("\nNAME : %s\n", setC.name);

  // Next improvement: Make it an array, because an array can be looped.
  // Note the nested curly braces to initialize the structs in the array.
  struct set setArr[] =
  {
    { {'o', 'h',  '!', '\0'} }, // character array initialized with single chars
    { SETA_NAME },
    { SETB_NAME },
    { SETC_NAME },
    { SETD_NAME },
    { "made up name"},         // extra members!
    { "Last not least name"},
  };

  // This is an idiom: You calculate the number of elements in an array 
  // by dividing the overall array size by the size of one member.
  // The beauty is that we don't have to change anything when the array size changes.
  // Alas, it does not work with pointers.
  const int structCount = sizeof(setArr)/sizeof(*setArr);

  printf("Loop:\n");
  for(int structInd=0; structInd < structCount; structInd++)
  {
      printf("NAME : ->%s<-\n", setArr[structInd].name);
  }

   // The name is the empty string, first char (like all others) is '\0'.
  printf("empty NAME : ->%s<-\n", empty.name);


}

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 140890

You are copying into the same struct each time.

memcpy(setA.name, SETA_NAME, sizeof(SETA_NAME));
       ^^^^^^^^^
memcpy(setA.name, SETB_NAME, sizeof(SETB_NAME));
       ^^^^
memcpy(setA.name, SETC_NAME, sizeof(SETC_NAME));
       ^^^^
memcpy(setA.name, SETD_NAME, sizeof(SETD_NAME));
       ^^^^
memcpy(setA.name, SETE_NAME, sizeof(SETE_NAME));
       ^^^^
memcpy(setA.name, SETF_NAME, sizeof(SETF_NAME));
       ^^^^

Upvotes: 5

Related Questions