0

I am using POSIX regex to parse a config file that looks like this:

ROOM NAME: XYZZY
CONNECTION 1: PLOVER
CONNECTION 2: Dungeon
CONNECTION 3: twisty
ROOM TYPE: START_ROOM

1) My algorithm depends on an array of pointers to the Room struct below. I want to instantiate a Room* object based on the data after the colons above. Actually, I want to plop the object directly into RoomArray[n] if possible. Anyways, below I created regexes instead of strtok, (but I suppose I could be convinced to use some string function.) I can't figure out how to stuff the capture group that would be called $2 in Perl for example, meaning the data per se.

2) How can "dereference" the array at Room->outBound in order to "push" the CONNECTION 1..N into it? Just doing RoomArray[0]->outBound[0] doesn't seem to work.

Here is my code. Thanks for any insight!

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h> // malloc
#include <math.h>
#include <time.h>
#include <sys/stat.h>
#include <regex.h>
#include <errno.h>

enum RoomType { START_ROOM, MID_ROOM, END_ROOM, END };

struct Room {
    char* name;
    int type;
    int id;
    int numConnects;
    struct Room* outBound[6];
};

int roomId;
struct Room* RoomArray[7];

/* this function cribbed from https://stackoverflow.com/a/16844977/9727704 */
enum RoomType getRoomType(char * val) {

    static char const * roomTypeArray[] = { "START_ROOM", "MID_ROOM", "END_ROOM" };
    int i;
    for (i = 0; i < END; ++i)
        if (!strcmp(roomTypeArray[i], val))
            return i;
    return END;
}

// slurp in a configfile
int parseFile(char *filename) {

    int rv;
    char buffer[100];
    FILE *fp;

    fp = fopen(filename, "r");

    if (fp == NULL) {
        fprintf(stderr, "Error opening file.");
        exit(1);
    }


    struct Room* RoomArray[roomId];
    struct Room* newRoom;

    /* each room file has three kinds of entries. We compile the regexes
     * for parsing the room files */

    /* the name of the room */
    regex_t name_regex;
    rv = regcomp(&name_regex, "^(ROOM NAME)(: )([a-zA-Z]+)\n$", REG_EXTENDED);
        if (rv) {
        fprintf(stderr, "Could not compile name_regex.\n");
        exit(1);
    }

    /* the names of the connections -- at least 3, less than 7 */
    regex_t conn_regex;
    rv = regcomp(&conn_regex, "^(CONNECTION [0-9])(: )([a-zA-Z]+)\n$", REG_EXTENDED);
        if (rv) {
        fprintf(stderr, "Could not compile conn_regex.\n");
        exit(1);
        }

    /* the kind of room it is */
    regex_t type_regex;
    rv = regcomp(&type_regex, "^(ROOM TYPE: )([a-zA-Z_]+)\n$", REG_EXTENDED);
        if (rv) {
        fprintf(stderr, "Could not compile type_regex.\n");
        exit(1);
        }

    while (fgets(buffer, 100, fp) != NULL ) {

        printf("buffer is %s\n",buffer);
        if (regexec(&name_regex, buffer, 0, NULL, 0) == 0) {
            puts("name match");
            newRoom->name = (char *) malloc(4 * sizeof(char));
            RoomArray[roomId]->name = (char *) malloc(4 * sizeof(char));

            // Cant figure out what to do without making valgrind puke all over my screen!

            //char* str = "foo";    
            //strcpy(RoomArray[roomId]->name,str);
            //strcpy(newRoom->name,"aaa");

        } else if (regexec(&conn_regex, buffer, 0, NULL, 0) == 0) {

            puts("conn match");

            // same here.

        } else if (regexec(&type_regex, buffer, 0, NULL, 0) == 0) {

            // I will use getRoomType() here to fill in Room->id    
            puts("type match");
        }
    }

    fclose(fp);

    /* free the memory */
    regfree(&name_regex);
    regfree(&type_regex);
    regfree(&conn_regex);

    roomId++;

    return 0;   
}


int main() {

    roomId = 0;
    char * filename = "room.txt";

    parseFile(filename);

    return 0;   
}

1 Answer 1

1

Your pointer array RoomArray gets dereferenced before it points to something.

RoomArray[roomId]->name

RoomArray[roomId] is not pointing to anything. You are missing something like

RoomArray[roomId]=malloc(sizeof(Room));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.