2014-12-03 4 views
-5

Моя программа вылетает, и я не могу найти, где. Я попробовал отладку с printf почти по каждой строке, но я просто не могу найти, что не так. Я ДУМАЮ, что он может быть у функции readLine, но я просто полностью потерян.Чтение и анализ комнат из текстового файла

файл ввода, который я использую

*HallStudyCellarKitchen*StudyHallGarden*CellarHall*KitchenHallGarden*GardenStudyKitchen 

Это означает, что каждый «*» отделяет новую комнату, а затем он показывает, где двери в этой комнате приводят к.

код моей программы

#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){ 
    struct room * r; // pointer r to the address of room 
    printf("New room is %s\n",name); 
    r = (struct room *) malloc(sizeof(struct room)); 
    r->name = name; // name of new room is name 
    r->dp = 0; // no doors 
    return r; 
}; 

showRoom(struct room * r){ 
    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(){ 
    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; 
    // printf("3"); fflush(stdout); 
    while((l = readLine(fin)) != NULL) 
    { 
     if(rp > MAX) 
     { 
      printf("it's too many rooms\n"); 
     exit(0); 
     } 
     //printf("%s",l); 
     rooms[rp] = newRoom(l); 
     //l = readLine(fin); 

     if (strncmp(l,"*")==0){ 
      //printf("2"); fflush(stdout); 
      rp++; 

     } 

     while(strncmp(l,"*")!=0) 
     { 
      //printf("1"); fflush(stdout); 
      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++; 
     l = readLine(fin); 

     } 
     //rooms[rp] -> dp = 0; 
     //rp++; 
     //l = readLine(fin); 
    } 
} 

connect() 
{ 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); 
    printf("22"); 
    fclose(fin); 
    showRooms(); 
    connect(); 
    r = rooms[0]; 
    while(1) 
    { showRoom(r); 
     printf("enter door number> "); 
     scanf("%d",&d); 
     if(d >= (r->dp)) 
     printf("bad door number\n"); 
     else 
     r = r->doors[d]->room; 
    } 

return EXIT_SUCCESS; 
} 

Что может быть причиной аварии, и как я могу решить это?

функция
+0

Какой выход вы получаете, когда он падает? Это поможет, если вы можете указать на часть кода, где он сбой. ваш printf должен привести вас куда-нибудь? –

+2

Это может быть отличным моментом, чтобы прекратить полагаться на printf для выполнения вашей отладки и получить некоторый опыт работы с фактическим отладчиком. – Bart

+0

'#include ' for 'strcmp' –

ответ

0

Readline действительно выглядит немного ошибки склонный:

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); 
    } 
    // The test on the next line is not necessary: it will be caught 
    // by the first run of the following while loop. 
    if (ch != '\n') 
     while (ch != '\n') 
      ch = getc(fin); 
    buffer[i] = '\0'; 
    // Allocate a region of memory of (probably) i+1 bytes 
    l = malloc((i+1) * sizeof(char)); 
    // j will range from zero to i, terminating when j = i+1 
    for (j = 0; j <= i; j++) 
     l[j] = buffer[j]; 
    // j now equals i+1 and l[j] is one beyond the size of the memory allocated at l. 
    l[j] = '\0'; 

    return l; 

} 

Устранить путем изменения состояния на петле

// j will range from zero to i-1, terminating when j = i 
    for (j = 0; j < i; j++) 
     l[j] = buffer[j]; 
    // j now equals i and l[j] is the last element of the memory allocated at l. 
    l[j] = '\0'; 

Примечания:

1) Вы всегда должны проверить возвращаемое значение от malloc.

2) Фактический размер памяти, выделенной malloc, может быть больше запрашиваемой, в зависимости от реализации кучи, архитектуры процессора и используемой фактической функции библиотеки.

Кроме того, вам должно быть приятно и позвонить free на каждый указатель, который вы назначили, используя malloc. Память будет очищена в конце концов, когда процесс завершится (если он работает в довольно распространенной ОС), но это хорошая практика для ведения домашнего хозяйства, особенно для тех временных буферов, которые возвращаются readLine.

Вы также можете взглянуть на строку if(rp > MAX) в readRooms и посмотреть, может ли привести к перерыву в 11-й комнате.

0

Неправильное использование int strncmp(const char *s1, const char *s2, size_t n); в 2-х местах. Предложите заменить strcmp().

// if (strncmp(l,"*")==0) 
if (strcmp(l,"*")==0) 

Если ваш компилятор не предупредил об этом, включите дополнительные предупреждения или получите новый компилятор.

Подозреваемый от на 1

// if (rp > MAX) 
if (rp >= MAX) 

// if((rooms[rp] -> dp) > 4) 
if ((rooms[rp] -> dp) >= 4) 

Мелкие исправления в readLine() следовать

char * readLine(FILE * fin){ 
    char buffer[BMAX]; 
    int i,j; 

    // char ch; 
    int ch; 

    char * l; 
    i = 0; 
    ch = getc(fin); 
    if (ch == EOF) 
    return NULL; 

    // while (ch!='\n' && i < (BMAX - 1)){ 
    while (ch!='\n' && ch!= EOF && i < (BMAX - 1)){ 

    buffer[i] = ch; 
    i++; 
    ch = getc(fin); 
    } 
    if (ch != '\n') 

    // while (ch != '\n') 
    while (ch != '\n' && ch!= EOF) 

     ch = getc(fin); 
    buffer[i] = '\0'; 

    // l = malloc((i+1) * sizeof(char)); 
    l = malloc(i+1); // sizeof(char) is always 1 
    if (l == NULL) Handle_OOM(); 

    for (j = 0; j <= i; j++) 
    l[j] = buffer[j]; 
    l[j] = '\0'; 

    return l; 

} 
0

Что может быть причиной аварии, и как я могу решить это?

Одним из возможных (и вероятно) причиной аварии является этот цикл в readRooms():

  while(strncmp(l,"*")!=0) 
     { 
      //printf("1"); fflush(stdout); 
      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++; 
     l = readLine(fin); 

     } 

l = readLine(fin) в конце цикла устанавливает l к NULL, когда EOF будет достигнут, и это нуль указатель ошибочно передан в strncmp() (также, как отметил chux, отсутствует третий аргумент).

Прежде чем вы сможете это решить, вы должны принять решение о формате входного файла, то есть говорить о том, будут ли номера проходить по одной и той же строке, как в вашем вопросе, - тогда вы не можете прочитать ни одного комната с readLine() в текущей форме - или комнаты идут по отдельным линиям.

Смежные вопросы