PDA

View Full Version : C, pointer to struct: assignment from incompatible pointer type / strcpy segfaults



tehet
February 22nd, 2008, 05:41 PM
Hi,
I'm trying to generate a list of cards (for learning structs and pointers) by looking at example program 5.2 (http://home.netcom.com/~tjensen/ptr/ch5x.htm). First I make a struct card{} and than a deck of 52 cards. Here deck is an array of a new data type card right?
Then I want a pointer of the type card to point to the first card in the deck (lines 23, 24) and finally some loops to generate the cards. Here's the code:

/* Cards */

#include <stdio.h>
#include <string.h>

/* char spade = 'S'; "\u2660"; unicode not working
char club = 'C'; "\u2663";
char heart = 'H'; "\u2665";
char diamond = 'D'; "\u2666"; */

char colours[] = {'S', 'C', 'H', 'D'};
char values[] = {2, 3, 4, 5, 6, 7, 8, 9, 0, 'J', 'Q', 'K', 'A'};

struct card{
char colour[1];
char value[1];
};

struct card deck[52];

int main()
{
struct card *card_ptr;
card_ptr = &deck; /* ------- line 24 -------- */
int i, n, card_num;
for (i = 0; i < 13; i++)
{
for (n = 0; n < 4; n++)
{
strcpy(deck[card_num].colour, colours[n]); /* Segmentation fault :( */
strcpy(deck[card_num++].value, values[i]);
}
}
/* show_deck(card_ptr); */
return 0;
}
It gives the following compiler warnings:

~/test$ gcc -g cards.c -o cards
cards.c: In function ‘main’:
cards.c:24: warning: assignment from incompatible pointer type
cards.c:30: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
cards.c:31: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
In short, I don't understand either the assignment warning nor the strcpy warning or how to get rid of them. Any hints on what I'm doing wrong?

And an unimportant question, is it possible to get unicode working in C? (for the spades, clubs, hearts and diamond symbols)

Thanks.

dwhitney67
February 22nd, 2008, 05:58 PM
It was easier for me to fix your code and compile it using my system than it was to compile it in my head.

Here's the corrected code:


/* Cards */

#include <stdio.h>
#include <string.h>

/* char spade = 'S'; "\u2660"; unicode not working
char club = 'C'; "\u2663";
char heart = 'H'; "\u2665";
char diamond = 'D'; "\u2666"; */

char colours[] = {'S', 'C', 'H', 'D'};
char values[] = {'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'}; // I changed this

struct card{
char colour[1];
char value[1];
};

struct card deck[52];

int main()
{
struct card *card_ptr = &deck[0]; // I changed this

int card_num = 0; // I changed this

for (int i = 0; i < 13; i++) // I changed this
{
for (int n = 0; n < 4; n++) // I changed this
{
strncpy( deck[card_num].colour, &colours[n], 1 ); // I changed this
strncpy( deck[card_num++].value, &values[i], 1 ); // I changed this
}
}

return 0;
}

Compiled successfully using gcc -std=c99. The execution was also successful.

P.S. I believe you were getting seg faults because you hadn't initialized card_num.

hod139
February 22nd, 2008, 06:09 PM
If I may make some general comments. In your card struct, why are you storing an array of 1 chars, instead of just a char? Why are you using strcpy to copy one char?



struct card{
char colour;
char value;
};

...

for (int i = 0; i < 13; i++) {
for (int n = 0; n < 4; n++) {
deck[card_num].colour = colours[n];
deck[card_num++].value = values[i];
}
}
Another important change that dwhitney67 made that he didn't mention in his post, is that he added single quotes around the numbers in your values array. This is important, because you want to store the char 2, not an auto-casted char of the int 2.

Edit: About your unicode question: http://www.cl.cam.ac.uk/~mgk25/unicode.html#c

dwhitney67
February 22nd, 2008, 06:17 PM
If I may make some general comments. In your card struct, why are you storing an array of 1 chars, instead of just a char? Why are you using strcpy to copy one char?

Good point!

tehet
February 22nd, 2008, 07:30 PM
In your card struct, why are you storing an array of 1 chars, instead of just a char?
Because in my broken version char colour[1] produced less compiler warnings than char colour[]. But yah, it's silly :)

Why are you using strcpy to copy one char?
Because I don't know what I'm doing :lolflag:

Thanks for the help guys! It's slowly starting to sink in, those wierd pointers and all.

sinisterstuf
June 3rd, 2010, 11:49 PM
Because I don't know what I'm doing :lolflag:


Awesome!

This post offers no real contribution other than to assure that you are not alone ;)

Can+~
June 3rd, 2010, 11:59 PM
Awesome!

This post offers no real contribution other than to assure that you are not alone ;)

But it assures that there's people who can't read the date of the thread before replying.