0

I am trying to initialize struct with a function.

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

#define NAME_SIZE 20
#define MANA_COST_SIZE 6
#define TYPE_SIZE 20
#define TEXT_SIZE 500
#define FLAVOR_SIZE 500
#define COLOR_SIZE 6

typedef struct card
{  
    char mana_cost[MANA_COST_SIZE];
    char name[NAME_SIZE];
    char type[TYPE_SIZE];
    char text[TEXT_SIZE];
    char flavor[FLAVOR_SIZE];
} card_t;

void init_card(card_t* card, char name[], char mana_cost[], char type[], char text[], char flavor[])
{  
    strcpy_s(card->name, NAME_SIZE, name);
    strcpy_s(card->mana_cost, MANA_COST_SIZE, mana_cost);
    strcpy_s(card->type, TYPE_SIZE, type);
    strcpy_s(card->text, TEXT_SIZE, text);
    strcpy_s(card->flavor, FLAVOR_SIZE, flavor);
}

main()
{  
    card_t* card;
    init_card(card, "Brainstorm", "u", "Instant", "Draw 3 cards, then put two cards from your hand on top of your library", "flavor");
    printf("%s\n", card->name);
}

The compiler gives the error: uninitialized local variable "card" used. Everything I have read suggests that this should be possible. I tried changing it to a pointer to a struct instead of the struct itself, but it was the same result. What am I missing?

  • Note: It's usually better to have `char*` with buffers sized to contents than have these hugely over-sized buffers with mostly nothing in them. – tadman Apr 27 '20 at 19:56
  • What's `strcpy_s()`? – Arkadiusz Drabczyk Apr 27 '20 at 19:56
  • 2
    Does this answer your question? [Update (int) variable in C inside a function](https://stackoverflow.com/questions/23667497/update-int-variable-in-c-inside-a-function) In the duplicate it's `int` is used as the type - it's the same principle, you just used `card_t`. – KamilCuk Apr 27 '20 at 20:03
  • @ArkadiuszDrabczyk It's (windows) addition to C standard available in (controversial, I say highly critiqued) optional Annex K. [cppreference](https://en.cppreference.com/w/c/string/byte/strcpy) Use `_CRT_SECURE_NO_WARNINGS` macro to disable warnings on windows. – KamilCuk Apr 27 '20 at 20:05
  • @KamilCuk It would, but I already tried using a pointer and the compiler gives the same result. I edited the posted code to reflect this. – Nicholas Babcock Apr 27 '20 at 20:10

1 Answers1

1

This is because you are passing a copy of your object. Therefore, in your function init_card the card is a local object and it doesn't change the one from the main function.

What you want to do is to use a pointer to a card:

void init_card(card_t *card, char name[], char mana_cost[], char type[], char text[], char flavor[])
{  
    strcpy(card->name, name);
    strcpy(card->mana_cost, mana_cost);
    strcpy(card->type, type);
    strcpy(card->text, text);
    strcpy(card->flavor, flavor);
}

int main()
{  
    card_t card;
    init_card(&card, "Brainstorm", "u", "Instant", "Draw 3 cards, then put two cards from your hand on top of your library", "flavor");
    printf("%s\n", card.name);
}

Note that I replaced your function strcpy_s with strcpy

The symbol & is used to retrieve the address of a variable.

Here card's type is card_t so &card is the address of a card_t, so it a card_t *

Mickael B.
  • 4,755
  • 4
  • 24
  • 48
  • Huh. I thought I had already tried using a pointer. I did `card_t* card` instead of `&card` and it gave the same error, but I just tried it your way and it worked! So thank you for the solution, but I think I am more confused now... – Nicholas Babcock Apr 27 '20 at 20:21
  • @NicholasBabcock I've edited the answer to explain `&` is used to retrieve the address of a variable. So `&card` will give you a `card_t *` – Mickael B. Apr 27 '20 at 20:58