在C语言中使用regex捕获组来填充一个结构。

问题描述 投票:0回答:1

我正在使用POSIX regex来解析一个配置文件,它看起来像这样。

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

1)我的算法依赖于下面Room结构的指针数组。我想根据上面冒号后的数据实例化一个Room*对象。其实,如果可能的话,我想把这个对象直接放入RoomArray[n]中。总之,下面我创建了regexes,而不是strtok,(但我想我可以被说服使用一些字符串函数。)我想不通如何塞入例如在Perl中会被称为$2的捕获组,也就是数据本身。

2)如何在Room->outBound处 "去引用 "数组,以便把CONNECTION 1...N "推 "进去?只做RoomArray[0]->outBound[0]似乎不行。

这是我的代码。谢谢你的任何见解!

#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;   
}
c regex pointers
1个回答
1
投票

你的指针数组 RoomArray 在指向某个东西之前就被取消引用。

RoomArray[roomId]->name

RoomArray[roomId]没有指向任何东西。你缺少了一些东西,比如

RoomArray[roomId]=malloc(sizeof(Room));
© www.soinside.com 2019 - 2024. All rights reserved.