不存储数据的结构指针的全局数组

时间:2019-01-17 09:09:55

标签: c struct

我有一个C语言程序,试图代表房屋的布局。它从具有以下格式的文本文件中读取房间:

Room
Door
Door
*
Room
Door
Door

房间和门作为结构存储,我有一个全局指针数组来存储10个房间。我正在使用方法readrooms()从文本文件中读取房间并将它们存储在数组中。但是,读完它后,当我尝试打印数组的内容时,会得到一串随机字符。

#include <stdio.h>
#define MAX 10
struct room * rooms[MAX];
int rp = 0; //room count

//Declare Structures
struct room {
    char *name;
    struct door *doors[4];
    int dp; //door count
};

struct door {
    char *name;
    struct room *room;
};

//Declare Functions
char *readLine(FILE *fin);
readrooms(FILE *fin);
struct  door *newDoor(char * name);
struct room *newRoom(char *name);

main(int argc, char const *argv[])
{
    FILE *f = fopen("C:\\Users\\s\\Documents\\C\\explore\\rooms.txt", "r");
    readrooms(f);
    printf("\n----- READ FILE SUCCESSFULLY | Room Count: %d -----\n", rp);

    for (int i = 0; i < rp; i++) {
        if (rooms[i] != NULL) {
            struct room r = *rooms[i];
            printf("ROOM %d: %s\n", i, r.name);
        }
    }


    return 0;
}

struct  door *newDoor(char * name) {
    struct door d;

    //TODO: MAKE SURE THIS IS RIGHT
    d.name = name;
    d.room = NULL;

    return &d;
}

struct room *newRoom(char *name) {
    struct room r;

    r.name = name;
    r.dp = 0;

    rooms[rp++] = &r;

    return &r;
}

char *readLine(FILE *fin) {
    char *str = (char *) malloc(sizeof(char) * 3);
    char current = fgetc(fin);
    int iter = 0;
    while (1) {
        if (current == '\n') {
            str[iter] = '\0';
            break;
        }
        else if (current == EOF) return NULL;
        else {
            str[iter++] = current;
           current = fgetc(fin);
        }
    }
    return str;
}

readrooms(FILE *fin) {
    char *curr_room = readLine(fin);

    while (curr_room != NULL) {
        if (strcmp(curr_room, "*") == 0) {
            curr_room = readLine(fin);
            continue;
        }
        struct room r = *newRoom(curr_room);
        printf("\n\nReading room %s\n", r.name);

        curr_room = readLine(fin);
        while (curr_room != NULL && strcmp(curr_room, "*") != 0) {
            struct door d = *newDoor(curr_room);
            d.room = &r;
            r.doors[r.dp++] = &d;

            printf("\t%s.doors[%d] = %s\n", r.name, r.dp-1, d.name);
            curr_room = readLine(fin);
            //printf("Current room is now %s\n\n", curr_room);
        }
    }

}

以下是输出:

Reading room Hall
        Hall.doors[0] = Study
        Hall.doors[1] = Cellar
        Hall.doors[2] = Kitchen


Reading room Study
        Study.doors[0] = Hall
        Study.doors[1] = Garden


Reading room Cellar
        Cellar.doors[0] = Hall


Reading room Kitchen
        Kitchen.doors[0] = Hall
        Kitchen.doors[1] = Garden


Reading room Garden
        Garden.doors[0] = Study
        Garden.doors[1] = Kitchen

----- READ FILE SUCCESSFULLY | Room Count: 5 -----
ROOM 0: ├ïuΣ uαΦ┤■  Y├jhxÖä
ROOM 1: É√o
ROOM 2: É√o
ROOM 3: É√o
ROOM 4: É√o

1 个答案:

答案 0 :(得分:2)

一个问题。

struct room *newRoom(char *name) {
    struct room r;

    r.name = name;
    r.dp = 0;

    rooms[rp++] = &r;

    return &r;
}

struct room r;是局部变量,一旦控件退出newRoom函数,该变量就会消失。

相反,您可以做的是

struct room *r = malloc(sizeof(struct room));
r->name = name;
r->dp = 0;

rooms[rp++] = r;

readLine中分配足够的内存以读取整行,否则最终将导致访问超出界限并调用未定义的行为。

 char *readLine(FILE *fin) {
    char *str = (char *) malloc(sizeof(char) * 256);
                                                 ^^^Max line length
     ...
  }

如果您不想盲目分配内存,realloc是您要寻找的东西。