2016-07-24 19 views
1

所以我認爲發生了什麼是我的頭節點不斷被覆蓋,但我不知道爲什麼。如果我刪除while循環,並且只是放入這樣的東西,它的工作就好了。雖然循環覆蓋C鏈接列表的頭節點在C

head = addItem(head, "item one"); 
head = addBack(head, "item two"); 

print(head); 

下面是代碼,因爲它是現在,下面我將包含頭函數與函數。請注意,我所有的菜單項目都沒有在循環中,一直在堅持讓鏈接列表正確一段時間。預先感謝您提供任何提示或建議。

主營:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include "functions.h" 

int menu(); 
void print(node *head); 
node* addItem(node *head, char *item); 
node* addBack(node *head, char *item); 


int main() 
{ 
    int selection; 
    char *item; 
    node* head = NULL; 
    char junk; 

    // Run the menu, and do something based on the selection 
    do { 
     selection = menu(); 
     // If they choose a number that's not between 1 and 3, or 0 
     if (selection > 3) { 
      printf("Please select a valid option\n"); 
     } 
     // If they enter 1, add an item to the list 
     else if (selection == 1) { 
      printf("Enter your list item: "); 
      // scanf leftover characters so fgets will work 
      scanf("%c", &junk); 
      fgets(item, 100, stdin); 
      if (head == NULL) { 
       head = addItem(head, item); 
      } 
      else if (head != NULL) { 
       addBack(head, item); 
      } 
     } 
     else if (selection == 3) { 
      // Print remaining items 
      print(head); 
     } 
    } while (selection != 0); 

return 0; 

} 

編輯:忘了補充在頭文件的功能。

struct node 
{ 
    char *item; 
    struct node *next; 
}; 

typedef struct node node; 


// Menu of choices, returns selection 
int menu() 
{ 
    int selection; 

    printf("\nChoose an option:\n1: Enter a list item \ 
    \n2: Delete a list item\n3: Print remaining items \ 
    \n0: Quit\n\n"); 
    scanf("%d", &selection); 

    return selection; 
} 

node* addItem(node *head, char *item) 
{ 
    node *tmp; 

    tmp = malloc(sizeof(node)); 
    tmp->item = item; 
    tmp->next = head; 
    head = tmp; 


    return head; 
} 

node* addBack(node *head, char *item) 
{ 

    node *tmp, *p; 
    tmp = malloc(sizeof(node)); 
    tmp->item = item; 
    p = head; 
    while (p->next != NULL) { 
     p = p->next; 
    } 
    p->next = tmp; 
    tmp->next = NULL; 

    return head; 
} 

void print(node* head) 
{ 
    node *tmp; 
    tmp = head; 
    if (tmp == NULL) { 
     printf("Add an item first, list is empty\n"); 
     exit(0); 
    } 
    while(tmp != NULL) 
    { 
     printf("%s\n ", tmp->item); 
     tmp = tmp->next; 
    } 
} 
+0

愚蠢的問題:如果選擇== 2? – clusterdude

回答

1

通過使用具有自動存儲持續時間item,其是不確定unintialized變量的值調用未定義行爲

在讀取輸入之前分配足夠的緩衝區。

else if (selection == 1) { 
    printf("Enter your list item: "); 
    // scanf leftover characters so fgets will work 
    scanf("%c", &junk); 
    /* add from here */ 
    item = malloc(100); 
    if (item == NULL) { 
     perror("malloc"); 
     return 1; 
    } 
    /* add until here */ 
    fgets(item, 100, stdin); 
    if (head == NULL) { 
     head = addItem(head, item); 
    } 
    else if (head != NULL) { 
     addBack(head, item); 
    } 
} 
+0

謝謝MikeCAT。看起來我沒有足夠的代表給你upvote,對此感到抱歉。感謝您解釋原因,我現在正在閱讀自動存儲。 –

+0

如果'item'沒有自動存儲持續時間,由於沒有分配緩衝區,他仍然會有未定義的行爲......只有(相關的)區別如果'item'具有靜態存儲持續時間將會是' NULL「,而不是一些未知的值。 – Dmitri

+0

如果'item'不是一個指針,而是一個有足夠元素的數組,那麼在節點中保存指向緩衝區的指針而不分配新緩衝區會導致最後一次從所有節點讀取字符串。 – MikeCAT