从命令行读取和连接房间

时间:2014-12-04 15:06:48

标签: c struct

首先,那是我的输入文件

Hall
Study
Cellar
Kitchen
*
Study
Hall
Garden
*
Cellar
Hall
*
Kitchen
Hall
Garden
*
Garden
Study
Kitchen
*

*之后的每一行是一个房间,其余的是那个房间的门。我的输出应该是这样的:

    Hall
    1. Study  
    2. Cellar 
    3. Kitchen
    enter door number> 3
    Kitchen
    1. Hall 
    2. Garden
    enter door number>

但我得到的只是:

 Hall
    1. Study
    2. Cellar
    3. Kitchen
    4. *
    Study
    1. Hall
    2. Garden
    3. *
    Cellar
    1. Hall
    2. *
    Kitchen
    1. Hall
    2. Garden
    3. *
    Garden
    1. Study
    2. Kitchen
    3. *
    gets here showrooms
    gets here showroom
    room name: Hall
    0 Hall
    Segmentation fault

它很可能是崩溃的connect()函数,因为我只能从showRooms获取最后3行,当它应该打印全部时。 继承我的计划:

#include <stdio.h>
#include <stdlib.h>

#define MAX 10
#define BMAX 100
struct room * rooms[MAX];
int rp; // room count


// struct room - name, array of up to 4 doors, number of doors
struct room {char * name; struct door * doors[4]; int dp;};
// struct door - name for the room it connects to, & a pointer to that room
struct door {char * name; struct room * room;};

struct door * newDoor(char * name){
    struct door * d; // pointer d to the address of door
    d = (struct door *) malloc(sizeof(struct door));
    d->name = name; // name of new door is name
    d->room = NULL; // NULL room pointer
    return d;

};

struct  room * newRoom(char * name){
    int i = 0;
    struct room * r; // pointer r to the address of room
    printf("%s\n",name);
//printf("New room is %s\n",name);
    r = (struct room *) malloc(sizeof(struct room));
    r->name = name; // name of new room is name

    for (i = 0; i < 4; i++){  // sets all doors to null for now
     r->doors[i] = NULL;

    }

    r->dp = 0; // no doors
    return r;
};

showRoom(struct  room * r){
    printf("gets here showroom\n");
    int i;
    printf("room name: %s\n", r->name);
        for (i = 0; i < (r->dp); r++){
            printf("%d %s\n", i,r->doors[i]->name);
        }
}

showRooms(){
printf("gets here showrooms\n");
    int i;
      for (i = 0; i < rp; i++){
    showRoom(rooms[i]);
      }
}


  char * readLine(FILE * fin){
  char buffer[BMAX];
  int i,j;
  char ch;
  char * l;
  i = 0;
  ch = getc(fin);
  if (ch == EOF)
    return NULL;
  while (ch!='\n' && i < (BMAX -1)){
    buffer[i] = ch;
    i++;
    ch = getc(fin);
  }
  if (ch != '\n')
    while (ch != '\n')
      ch = getc(fin);
  buffer[i] = '\0';
  l = malloc((i+1) * sizeof(char));
  for (j = 0; j <= i; j++)
    l[j] = buffer[j];
    l[j] = '\0';
  return l;

}

readRooms(FILE * fin){

    char * l;
    rp = 0;

    while((l = readLine(fin)) != NULL)
    {  
      if(rp > MAX)
      {  
     printf("it's too many rooms\n");
         exit(0);
      }
        rooms[rp] = newRoom(l);

    printf("", l);
         while(strncmp(l,"*")!=0) 
      {     

       if((rooms[rp] -> dp) > 4){
              printf("it's too many doors\n");
                   exit(0);
            }
         rooms[rp] -> doors[rooms[rp] -> dp] = newDoor(l);
         rooms[rp] -> dp = (rooms[rp] -> dp) + 1;
         l = readLine(fin);
     printf("%d. %s\n", rooms[rp] -> dp, l);
      }
        rp++;

   }
}

connect()
{  
   printf("gets here connect\n");
   int i,j,k;
   for(i = 0; i < rp; i++)
    for(j = 0; j < (rooms[i]->dp); j++)
    {  for(k = 0; k < rp; k++)
        if(strcmp(rooms[k]->name,rooms[i]->doors[j]->name) == 0)
        {  rooms[i]->doors[j]->room = rooms[k];
           break;
        }
       if(k == rp)
       {  printf("can't find %s\n",rooms[i]->doors[j]->name);
          exit(0);
       }
    }
}

int main(int argc,char ** argv){
    FILE * fin;
    struct room * r; // current room
   // struct door * d;
   int d;

    if((fin=fopen(argv[1],"r"))==NULL)
   {  printf("cannot open %s\n",argv[1]);
      exit(EXIT_FAILURE);
   }
   //printf("11"); fflush(stdout);
   readRooms(fin);
   fclose(fin);
   showRooms();
   connect();
   r = rooms[0];
   while(1)
   {  showRoom(r);
      printf("enter door number> ");
      scanf("%d",&d);
    printf("%d",r->dp);
       if(d >= (r->dp))
       printf("bad door number\n");
      else
       r = r->doors[d]->room;
   }

return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:0)

这里有几个问题。

首先,您的阅读功能没有正确找到星号,因为您使用strncmp的参数数量错误且没有来自<string.h>的原型。然后你应该首先在循环之外读取一个字符串,然后在循环中读取最后一件事:

void readRooms(FILE * fin)
{
    char *l;

    rp = 0;

    while ((l = readLine(fin)) != NULL) {
        if (rp > MAX) {
            printf("it's too many rooms\n");
            exit(0);
        }
        rooms[rp] = newRoom(l);

        l = readLine(fin);
        while(l && strcmp(l, "*") != 0) {
            if ((rooms[rp]->dp) > 4) {
                printf("it's too many doors\n");
                exit(0);
            }
            rooms[rp]->doors[rooms[rp]->dp] = newDoor(l);
            rooms[rp]->dp = (rooms[rp]->dp) + 1;
            printf("%d. %s\n", rooms[rp]->dp, l);

            l = readLine(fin);
        }
        rp++;
    }
}

请注意l条件中while的额外检查,因为getline在找到文件末尾时可能会返回NULL。另请注意,readLine的实现每次都会泄漏内存,因为您已分配,但您永远不会free。你也可以在分配的内存之外写,因为循环后j将是i + 1 - 你已经循环到'j&lt; = i`。

接下来,您的例程都将指向line的指针存储为房间和门的名称。这意味着,所有房间都被称为"*"。您应该使用strdup复制字符串。

您的connect函数可能更好地呈现为两个函数。在showRoom中,您增加房间指针r而不是i。增加i

void showRoom(struct room * r)
{
    int i;

    printf("room name: %s\n", r->name);
    for (i = 0; i < (r->dp); i++) {
        printf("%d %s\n", i, r->doors[i]->name);
    }
}

这至少应该让你开始走进房间。但是,您的代码存在更多问题,尤其是内存管理。