2014-12-03 28 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應該引導你到什麼地方? – 2014-12-03 11:18:31

+2

這可能是一個很好的時間點,可以停止依靠printf來進行調試並獲得一些實際調試器的使用經驗。 – Bart 2014-12-03 11:19:06

+0

'#include ''strcmp' – 2014-12-03 11:22:23

回答

0

readline的功能看起來確實有點錯誤傾向:通過在環

// 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'; 

說明改變情況

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; 

} 

修復此:

1)您應經常檢查返回值從malloc

2)由malloc分配的內存的實際大小可能會大於請求的大小,具體取決於堆實現,處理器體系結構和實際使用的庫函數。

此外,您應該很好,並且使用malloc對每個已分配的指針調用free。當進程終止時(如果它運行在一個相當普通的操作系統中),內存將被最終清理,但是最好是做家務,尤其是在由readLine返回的臨時緩衝區中。

您可能還想看看readRooms中的if(rp > MAX)一行,看看是否可能導致第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)在循環結束時將lNULL當EOF達到,並且該空指針被錯誤地傳遞給strncmp()(也就是說,正如chux所指出的,錯過了第三個參數)。

在你解決這個問題之前,你必須對輸入文件格式作出決定,也就是說房間是否在同一行上,就像你的問題 - 然後你不能讀一個單一的房間以readLine()的當前形式 - 或者房間分開放置。