winegum
winegum

Reputation: 43

c define struct in another c file

I have delcared a struct in my header file and now i want to define an array of this struct in another c-file to seperate it from my main c-file. The definition of the components is not possible in the second c-file the way i try it (see code below). How can I define the struct in another c-file (or h-file, but i think there should be no definitions in h-files).

main.c

#include "struct.h"
int main(void)
{
    printf("%s",room[0].name);
    return 0;
}

struct.h

struct RoomStruct
{
    char name[20];
    int rRight, rLeft, rFront, rBack, rUp, rDown;
};
typedef struct RoomStruct Room;

extern Room rooms[20];

struct.c

#include <string.h>

#include "struct.h"

Room rooms[20];

strcpy(rooms[0].name,"firstRoom");
rooms[0].rLeft = 1;

Upvotes: 3

Views: 4496

Answers (2)

Walter Delevich
Walter Delevich

Reputation: 427

As mah said, you can't just place instructions in a file outside of any function scope. You can declare an instance of the structure though.

As for how you could reference a variable declared in another file, you would use the extern keyword.

room.c

#include "room.h"
struct room my_room;

main.c

#include "room.h"
extern struct room my_room;

The extern declaration tells the compiler that the memory for the given variable is defined in some other to-be-linked file. There's no reason not to define a structure in main that you've defined in another header file though, I would not use externs like this.

Upvotes: 0

embedded_guy
embedded_guy

Reputation: 1967

As @mah recommends, I would consider calling functions to keep your data separate. This has the added value of keeping "spaghetti code" out of your codebase. For example, if you have a global array of Room struct it can be called from anywhere. Having a static array of Room struct within a file is a better practice (IMHO). Here is a simple example that I worked out:

main.c

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

int main (void)
{
    Room localRoom[20];

    strcpy(localRoom[0].name, "firstRoom");
    StructFunc_UpdateStruct(localRoom);
    strcpy(localRoom[0].name, "renamed");
    StructFunc_Print();
    printf("%s", localRoom[0].name);

    return 0;
}

struct.h

typedef struct
{
    char name[20];
    int rRight, rLeft, rFront, rBack, rUp, rDown;
} Room;

void StructFunc_UpdateStruct(Room * roomData);
void StructFunc_Print(void);

StructFunc.c

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

static Room gRoom[20];

extern void StructFunc_UpdateStruct(Room * roomData)
{
    strcpy(gRoom[0].name, roomData[0].name);
}

extern void StructFunc_Print(void)
{
    printf("%s\r\n", gRoom[0].name);
}

I hope that helps!

EDITED BASED ON COMMENT
I would assume (based on your comment) that you would like to be able to rebuild this program with different "rooms" depending on which .c file you use to compile with. If that is what you are trying to achieve, then this should work for you:

main.c

#include "struct.h"
#include <stdio.h>

int main (void)
{
    printf("%s", rooms[0].name);
    return 0;
}

struct.h

#define NUM_OF_ROOMS    2
#define MAX_STRING_SIZE 20

typedef struct
{
    char name[MAX_STRING_SIZE];
    int rRight, rLeft, rFront, rBack, rUp, rDown;
} Room;

extern Room rooms[];

struct.c

#include "struct.h"

Room rooms[NUM_OF_ROOMS] =
{
    /* Room 0 */
    {
      /* Name       rRight  rLeft   rFront  rBack   rUp     rDown   */
        "Living",   1,      2,      3,      4,      5,      6
    },
    /* Room 1 */
    {
        "Dining",   2,      3,      4,      5,      6,      0
    }
};

SIMPLER BUILD FORMAT

Another option would be to add a #define so that you don't have to change the files that you are building - just change the value of the #define like so:

struct.h

#define MAP_NUMBER      0   //Change this value to use a different map.
#define NUM_OF_ROOMS    2
#define MAX_STRING_SIZE 20

typedef struct
{
    char name[MAX_STRING_SIZE];
    int rRight, rLeft, rFront, rBack, rUp, rDown;
} Room;

extern Room rooms[];

struct.c

#include "struct.h"

#if (MAP_NUMBER == 0)
Room rooms[NUM_OF_ROOMS] =
{
    /* Room 0 */
    {
      /* Name       rRight  rLeft   rFront  rBack   rUp     rDown   */
        "Living",   1,      2,      3,      4,      5,      6
    },
    /* Room 1 */
    {
        "Dining",   2,      3,      4,      5,      6,      0
    }
};
#elif (MAP_NUMBER == 1)
Room rooms[NUM_OF_ROOMS] =
{
    /* Room 0 */
    {
      /* Name       rRight  rLeft   rFront  rBack   rUp     rDown   */
        "Kitchen",   1,      2,      3,      4,      5,      6
    },
    /* Room 1 */
    {
        "Bathroom",   2,      3,      4,      5,      6,      0
    }
};
#else
Room rooms[NUM_OF_ROOMS] =
{
    /* Room 0 */
    {
      /* Name       rRight  rLeft   rFront  rBack   rUp     rDown   */
        "Bedroom",   1,      2,      3,      4,      5,      6
    },
    /* Room 1 */
    {
        "Dungeon",   2,      3,      4,      5,      6,      0
    }
};
#endif

Upvotes: 1

Related Questions