Reputation: 467
I came up with a project to work on learning C and I have kind of hit a wall. The project is simply a card game where the player has two sets of cards, one set is a deck of a set size and the other is their collection of cards that can be as big as it needs to be. The card structure is as follows:
struct card {
char name[256];
char special[256];
char type[100];
char rarity[100];
int points;
};
I then have a file of the collection called coll.txt
first card goes here 50
second card goes here 70
...
I then have a (sloppy) function that reads from the file and stores it into a temporary card:
void read_into_collection(FILE *f) {
char *file_text;
char *token;
int i;
struct card temp;
file_text = (char *) malloc(sizeof(struct card));
while(fgets(file_text, sizeof(struct card), f)) {
for(i = 1, token = strtok(file_text, " "); token; i++, token = strtok(NULL, " ")) {
switch (i) {
case 1:
strcpy(temp.name, token);
break;
case 2:
strcpy(temp.special, token);
break;
case 3:
strcpy(temp.type, token);
break;
case 4:
strcpy(temp.rarity, token);
break;
case 5:
temp.points = atoi(token);
break;
default:
i = 0;
break;
}
}
}
free(file_text);
}
so by the time i = 6
I am ready to move the temporary card to the collection and read the next card into the temp variable and so on. But how do I do this? I am having trouble figuring out what collection should actually be. At first I thought:
struct card *collection = (struct card *) malloc(number_of_cards * sizeof(struct card));
But, if I am correct, malloc()
returns a pointer to a chunk of memory and the memory is not sequential like an array, so I cannot increment the pointer to store cards.
I also tried counting the number of lines in the file (each line is a card) and then making an array of that size but I get an error that the value is not constant.
What is the best way to go about storing these cards as a collection? I would just make the collection a really large array but I feel like this situation comes up often in projects and would rather learn how to handle it rather than take the easy way out.
Upvotes: 2
Views: 227
Reputation: 60848
But, if I am correct, malloc() returns a pointer to a chunk of memory and the memory is not sequential like an array, so I cannot increment the pointer to store cards.
False. It is sequential. You can use malloc()
to create an array of anything:
mystruct* ptr = (mystruct*) malloc(sizeof(mystruct) * numberOfStructs)
for(int i = 0; i < numberOfStructs, i++) {
ptr[i].setSomeInfo(x);
}
This is the standard way to do it in C.
Upvotes: 3
Reputation: 126
I used to program in C a lot more, one of my favorites. Here is my answer.
The way you've used malloc did allocate an array
struct card *collection = (struct card *) malloc(number_of_cards * sizeof(struct card));
Each call to malloc will return a pointer to a different area in memory. But one call to malloc always returns a contiguous block.
If number of cards is known, you could use that to allocate an array and then access it like so
//added some code to prevent overflow
collection[i].name[255] = 0;
strncpy(collection[i] .name, token, 255);
What if number of cards is not known. Then do a linked list. That is primary use of a linked list, storing the contents of a collection whose size is unknown.
Upvotes: 1