Reputation: 25
I'm trying to represent a battle cards game :
typedef struct list_of_cards* p_loc;
typedef struct game game_s;
struct list_of_cards {
char card[4]; // card is represented like 10C or KS
p_loc ncards; // next card
};
struct game {
p_loc loc; // list of card
p_loc lcard; // last card
};
p_loc init_cards(p_loc loc, int n) {
loc = malloc(sizeof(struct list_of_cards));
scanf("%s", loc->card);
fprintf(stderr, "%s\n", loc->card);
if (n == 1)
return loc;
init_cards(loc->ncards, n-1);
}
int main()
{
int n; // the number of cards for player 1
scanf("%d", &n);
game_s player1;// the n cards of player 1
player1.lcard = init_cards(player1.loc, n);
fprintf(stderr, "%s %s\n", player1.loc->card, player1.lcard->card);
}
The first fprintf
give me what I want (like AD KC QC) but the second displays
�(�� QC
. So my question is, why �(�� is player1.loc->card value. Thanks
Upvotes: 2
Views: 64
Reputation: 7193
The reason why player1.loc->card is some weird string is due to the fact it is uninitialized and the memory contains random characters which are not always printable in ascii
.
You need to modify your loc
in your init to do so you can pass your loc
as a pointer to the first element of your list,but the best way is probably to initialize you whole player struct in one function.
p_loc init_cards(p_loc* loc, int n) {
*loc = malloc(sizeof(struct list_of_cards));
scanf("%s", (*loc)->card);
fprintf(stderr, "%s\n", (*loc)->card);
if (n == 1)
{
(*loc)->ncards = NULL;
return *loc;
}
return init_cards(&((*loc)->ncards), n-1);
}
int main()
{
int n; // the number of cards for player 1
scanf("%d", &n);
game_s player1;// the n cards of player 1
player1.lcard = init_cards(&player1.loc, n);
fprintf(stderr, "%s %s\n", player1.loc->card, player1.lcard->card);
}
Upvotes: 3
Reputation: 211278
You have to return the allocate card and assign it back to the member p_loc
of its predecessor.Further you need an output parameter for the last card of the deck:
p_loc init_cards( int n, p_loc *lastCard )
// ^ output parameter
{
if ( n <= 0 ) // terminate recursion
return NULL; // successor of last card is NULL
p_loc loc = malloc(sizeof(struct list_of_cards)); // allocate new card
if ( loc != NULL )
{
scanf("%s", loc->card);
fprintf(stderr, "%s\n", loc->card);
*lastCard = loc; // new card is last card
loc->ncards = init_cards( n-1 ); // next card is successor of act card
}
return loc; // return new card
}
int main()
{
int n; // the number of cards for player 1
scanf("%d", &n);
game_s player1;// the n cards of player 1
player1.lcard = NULL;
player1.loc = init_cards( n, &player1.lcard );
fprintf(stderr, "%s %s\n", player1.loc->card, player1.lcard->card);
}
But you can easily do that without recursion:
p_loc init_cards( int n, p_loc *lastCard )
{
*lastCard = NULL;
p_loc head;
p_loc *act = &head; // init pointer to first card
for ( int i = 0; i < n; i ++ )
{
*act = malloc( sizeof(struct list_of_cards) ); // allocate next card right to target
if ( *act == NULL )
break;
scanf( "%s", (*act)->card );
fprintf( stderr, "%s\n", (*act)->card );
*lastCard = *act; // last card is act card
act = &((*act)->ncards); // set pointer to member ncards of last card
}
*act = NULL; // successor of last card is NULL
return head; // return first card
}
Upvotes: 2