Search code examples
carraysstructdefinitionextern

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;

Solution

  • 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