2016-07-24 51 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