2016-05-13 70 views
1

我的雙向鏈表上書面方式程序與數據結構如下:Ç - 雙向鏈表總是空

typedef struct telephoneBookNode { 
    int id; 
    char name[NAME_LENGTH]; 
    char telephone[TELEPHONE_LENGTH]; 
    struct telephoneBookNode * previousNode; 
    struct telephoneBookNode * nextNode; 
} TelephoneBookNode; 

typedef struct telephoneBookList { 
    TelephoneBookNode * head; 
    TelephoneBookNode * tail; 
    TelephoneBookNode * current; 
} TelephoneBookList; 

在下面的功能,我從一個文本文件中讀取數據到鏈表中,文件內容是這樣的:

/*100, Alice, 0411112222 
101, Bob, 0411112222 
102, Ali, 0411112223*/ 

TelephoneBookList * commandLoad(char* fileName) { 
    TelephoneBookList *(*createList)(TelephoneBookNode*, char[]) = createTelephoneBookList; 

    char entry[100], *temp1, *temp2; 
    TelephoneBookList* aList = NULL; 
    TelephoneBookNode* aNode = NULL; 
    FILE* telephoneListFile = NULL; 
    int countEntry = 0; 
    Boolean check; 

    telephoneListFile = fopen(fileName, "r"); 

    if (!telephoneListFile) 
     return NULL; 
    else { 
     while (fgets(entry, 100, telephoneListFile)) { 
      temp2 = strcpy(temp2, entry); 
      temp1 = strtok(entry, "\n"); 
      check = addressBookEntryCheck(temp1); 

      if (!check) 
       return NULL; 
      else 
       //here I pass aNode pointer to the below function 
       aList = (*createList)(aNode, temp2); 
     } 
     fclose(telephoneListFile); 
     printf("printed"); //This line is reached when program complied 
     return aList; 
    } 
} 

這是創建列表的功能,問題可能出在這裏:它亙古不增加新的節點列表,它只是替換爲新的一個第一個節點。最後,鏈表只有1個記錄,它是文本文件中的最後一個記錄。我如何修復代碼?謝謝!

TelephoneBookList * createTelephoneBookList(TelephoneBookNode* node, char entry[]) { 
    TelephoneBookList* aList = malloc(sizeof *aList); 
    TelephoneBookNode* aNode = (TelephoneBookNode*) malloc(sizeof *aNode); 
    char *tokens; 

    tokens = strtok(entry, ", "); 
    aNode->id = atoi(tokens); 

    tokens = strtok(NULL, ", "); 
    strcpy(aNode->name, tokens); 

    tokens = strtok(NULL, ", "); 
    strcpy(aNode->telephone, tokens); //Just assigning values to a node 

    //program always go to this block, means `node` is always null 
    if (node == NULL) { 
     aNode->nextNode = NULL; 
     aNode->previousNode = NULL; 
     node = aNode; 

     aList->current = node; 
     aList->head = node; 
     aList->tail = node; 
    } 
    else { //This block is not reached 
     while (node->nextNode) 
      node = node->nextNode; 

     node->nextNode = aNode; 
     aNode->previousNode = node; 

     aList->tail = node->nextNode; 
    } 
    return aList; 
} 

這是檢查函數入口:

Boolean addressBookEntryCheck(char entry[]) { 
    char *tokens; 

    tokens = strtok(entry, ", "); 

    if(!tokens || strlen(tokens) < 1 || strlen(tokens) > 3) 
     return FALSE; 
    else { 
     if (!isNumber(tokens)) 
      return FALSE; 
     else { 
      tokens = strtok(NULL, ", "); 

      if (!tokens) 
       return FALSE; 
      else 
      { 
       tokens = strtok(NULL, ", "); 

       if (!tokens) 
        return FALSE; 
       else if (!isNumber(tokens) || strlen(tokens) != 10) 
        return FALSE; 
       else 
        return TRUE; 
      } 
     } 
    } 
} 
+0

據透露, 'node = ...'對你函數的*調用者沒有意義。該指針是通過值傳遞的(所有更改都是在函數內部的自動局部變量)。 – WhozCraig

+0

如何'addressBookEntryCheck'樣子?如果它總是返回true,你會得到你描述的行爲。如果我是你,我會讓這個功能做的更少一些,使得它更容易遵循,即一個函數創建列表頭,一個添加節點。 –

+0

我已經添加了函數'addressBookEntryCheck',它實際上總是返回'false',甚至沒有錯誤的入口格式。 –

回答

0

每次調用

createTelephoneBookList 

創建一個新的列表時,

TelephoneBookList* aList = malloc(sizeof *aList); 

也複製到未初始化的指針

temp2 = strcpy(temp2, entry); 

我會建議你創建一個函數來創建列表標題,一個函數添加新項目,例如

aList = createList() 
while (fgets(entry,sizeof(entry),fp)!=NULL) 
{ 
    if (!addEntry(aList,entry)) 
    { 
    fprintf(stderr, "failed additem item %s\n", entry); 
    } 
} 
... 

在addEntry的解析字符串

int id = 0; 
char name[NAME_LENGTH]; 
char telephone[TELEPHONE_LENGTH]; 

p = strtok(entry, ","); // id 
if (p != NULL) 
{ 
    id = atoi(p); 
    p = strtok(NULL, ","); // name, store to temporary string 
    if (p != NULL) 
    { 
    strcpy(name,p); 
    p = strtok(NULL, ","); // telephone number, store to temporary string 
    if (p != NULL) 
    { 
     strcpy(telephone,p); 

     // here you can allocate the new node 
    } 
    } 
} 

// disclaimer omitted checks for length etc which any good program should have. also make sure you have room for \0 

如果上述任何strtok失敗返回0,否則分配一個新的條目

TelephoneBookNode* aNode = malloc(sizeof(TelephoneBookNode)); 
aNode->id = id; 
strcpy(aNode->name, name); 
strcpy(aNode->telephone, telephone); 

然後添加到您的aList

0
//program always go to this block, means `node` is always null 
    if (node == NULL) { 
    .... 

這是因爲該函數的調用者通過aNode,它從來不是循環內改變。因此,它總是會通過的aNode這是NULL相同的值。

我還沒有詳細看過你的代碼的邏輯,但我想你可能想通過aList->head,或者你已經通過aList,所以就使用它。