# C programming Q: initializing an array of structures

I am writing a program in C (vanilla, non-C++/C#) and I am having trouble figuring out why my initialization of my array of structures isn't working. I have tried a number of things without any luck. I still get a compiler error: "conflicting types for 'cardInfo' "

I am writing a simple implementation of a card game (Dominion) and each card has different costs, effects, etc. So I was going to make a struct, plop a bunch into an array (we only need to implement 27 cards, already specified) so that I could access various bits of info about them more easily (I need the cost in the Buying phase, the Coins and Actions in another phase, etc).

There is an ENUM earlier in the program that defines the names 'curse', 'estate', 'treasure_map' and others. So I am using those enums as indexes (as well as defining the array size). So when defining the array elements (the cardDef structures) I am trying to set the 0-index element as the Curse card ('curse' enum is 0), the 1-index as "Estate" ('estate' enum is 1).

Code:
struct cardDef {
char name[MAX_NAME];
enum CARDTYPES card_type;
int card_cost;
int victory_points;
};

struct cardDef cardInfo[treasure_map + 1];  /*my attempted array declaration  */

/*Trying to initialize the elements of the array here.  This first line is where I get the
compiler error; the other lines are examples of other styles that still got the same error.   */
struct cardDef cardInfo[curse] = {"Curse", CURSE, 0, -1, 0, 0, 0};
cardDef cardInfo[duchy]  = {"Duchy", VICTORY, 5, 3, 0, 0, 0};
cardInfo[estate]  = {"Estate", VICTORY, 2, 1, 0, 0, 0};

Any pointers (haha - no C pointers please) and help would be appreciated. I imagine that it is something simple, but the various references and tutorials that I have found on this seem to point to the method that I use in the first line. No love from GCC, though. And it's late, and I am cross-eyed from staring at this. :)

Thanks!
Justin

Mark44
Mentor
I am writing a program in C (vanilla, non-C++/C#) and I am having trouble figuring out why my initialization of my array of structures isn't working. I have tried a number of things without any luck. I still get a compiler error: "conflicting types for 'cardInfo' "

I am writing a simple implementation of a card game (Dominion) and each card has different costs, effects, etc. So I was going to make a struct, plop a bunch into an array (we only need to implement 27 cards, already specified) so that I could access various bits of info about them more easily (I need the cost in the Buying phase, the Coins and Actions in another phase, etc).

There is an ENUM earlier in the program that defines the names 'curse', 'estate', 'treasure_map' and others. So I am using those enums as indexes (as well as defining the array size). So when defining the array elements (the cardDef structures) I am trying to set the 0-index element as the Curse card ('curse' enum is 0), the 1-index as "Estate" ('estate' enum is 1).

Code:
struct cardDef {
char name[MAX_NAME];
enum CARDTYPES card_type;
int card_cost;
int victory_points;
};

struct cardDef cardInfo[treasure_map + 1];  /*my attempted array declaration  */

/*Trying to initialize the elements of the array here.  This first line is where I get the
compiler error; the other lines are examples of other styles that still got the same error.   */
struct cardDef cardInfo[curse] = {"Curse", CURSE, 0, -1, 0, 0, 0};
cardDef cardInfo[duchy]  = {"Duchy", VICTORY, 5, 3, 0, 0, 0};
cardInfo[estate]  = {"Estate", VICTORY, 2, 1, 0, 0, 0};

Any pointers (haha - no C pointers please) and help would be appreciated. I imagine that it is something simple, but the various references and tutorials that I have found on this seem to point to the method that I use in the first line. No love from GCC, though. And it's late, and I am cross-eyed from staring at this. :)

Thanks!
Justin

You are attempting to declare and/or define cardInfo multiple times. This declaration
Code:
struct cardDef cardInfo[treasure_map + 1];
indicates that cardInfo is an array of (treasure_map + 1) cardDef elements.

Here you are redefining cardInfo
Code:
struct cardDef cardInfo[curse] = {"Curse", CURSE, 0, -1, 0, 0, 0};
as an array of (curse) cardDef elements. This is why you are getting the error you're seeing.

A similar thing is happening with these definitions.
Code:
cardDef cardInfo[duchy]  = {"Duchy", VICTORY, 5, 3, 0, 0, 0};
cardInfo[estate]  = {"Estate", VICTORY, 2, 1, 0, 0, 0};

You can initialize an array of structs at the place where you define the array, but you can't define the array as you did in the first line, and then come back later and assign a struct value to one of the elements of the array.

If your book doesn't have any examples of initializing an array of structs, see http://www.mycplus.com/tutorials/c-programming-tutorials/unions-structures/1/ and http://www.mycplus.com/tutorials/c-programming-tutorials/unions-structures/2/.

Last edited by a moderator:
After a nice long nap, I see what you are getting at now. Thanks!

So it seems that the way to initialize it is to do either member by member:

Code:
cardInfo[curse].name = "Curse";
cardInfo[curse].card_type = CURSE;
cardInfo[curse].card_cost = 0;

etc.

Or initialize it at declaration time:

Code:
struct cardDef cardInfo[treasure_map +1] = {
{"Curse", CURSE, 0, -1, 0, 0, 0},
{"Duchy", VICTORY, 5, 3, 0, 0, 0},
...
}

I got stuck on thinking that it was just like setting array values, where the equals sign was enough for the compiler to recognize that it is an assignment to that index instead of a declaration of the array w/ that many elements. Ah, the intricacies of C! :)

Thanks again,
Justin

Mark44
Mentor
After a nice long nap, I see what you are getting at now. Thanks!

So it seems that the way to initialize it is to do either member by member:

Code:
cardInfo[curse].name = "Curse";
cardInfo[curse].card_type = CURSE;
cardInfo[curse].card_cost = 0;
Sort of. You can assign values like so to the card_type and card_cost members, but not to the name member. What your first assignment statement here does is to store a memory location into name, which is in essence a pointer.

For this member you should use one of the standard library functions such as strcpy. So the first line above would look like this:
Code:
strcopy(cardInfo[curse].name, "Curse");
This will actually copy the characters in "Curse" to the name member of the struct. Be sure to #include <string.h> for the declaration of strcpy().
etc.

Or initialize it at declaration time:

Code:
struct cardDef cardInfo[treasure_map +1] = {
{"Curse", CURSE, 0, -1, 0, 0, 0},
{"Duchy", VICTORY, 5, 3, 0, 0, 0},
...
}

I got stuck on thinking that it was just like setting array values, where the equals sign was enough for the compiler to recognize that it is an assignment to that index instead of a declaration of the array w/ that many elements. Ah, the intricacies of C! :)
Remember that you can't set a character array by assignment for the reason given above. You can set the individual character elements of such an array or you can use strcpy or another function to do this.

You can initialize a character array, but this is different from assigning a string value to a string (really, character array or pointer to a character).

IOW, this will work:
Code:
char name[10] = "Fred";

but this won't.
Code:
char name[10];
name = "Fred";
In the first example, the array name is being initialized with the string constant. In the second, the compiler will generate an error, because name is not an lvalue (i.e., name cannot appear on the left side of an assignment statement.

Hope that helps.

OK, thanks for the clarifications. I think I have a better handle on it now.

Is the only way to assign data to the structures, if I don't do it at declaration, to do it member by member, though? I keep thinking about only filling the array of structures with cards that are actually being used (27 are defined, only 17 or so are used).

Thanks,
Justin

Mark44
Mentor
OK, thanks for the clarifications. I think I have a better handle on it now.

Is the only way to assign data to the structures, if I don't do it at declaration, to do it member by member, though?
Yes.
I keep thinking about only filling the array of structures with cards that are actually being used (27 are defined, only 17 or so are used).

Thanks,
Justin

Bummer, but good to know. :)

Thanks again for all the pointers.

-- Justin