代码之家  ›  专栏  ›  技术社区  ›  Anton S.

程序更新链表

c
  •  1
  • Anton S.  · 技术社区  · 6 年前

    我正在尝试创建一个带有名称的链接列表,例如:

    Tom -> David -> John...

    我的主要职能是 switch 菜单,程序询问您是否要创建新列表或退出。

    1 insertIntoLinkedList(name, &head)

    一切正常,但是如果用户输入 end 然后选择选项 1 同样,程序创建了一个新的 linked list 但是我想把名字添加到现有的列表中。

    编辑

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define NAME_SIZE 30
    #define EXIT "end"
    
    // Node structure
    struct node {
      char name[NAME_SIZE];
      struct node *next;
    };
    
    typedef struct node Node;
    typedef struct node* NodePointer;
    
    int userChoice(void);
    void insertIntoLinkedList(char [], NodePointer *);
    void displayNames(NodePointer);
    
    int nodeCounter = 0;
    
    int main(void) {
      int choice = 99;
    
      do {
          printf("\n--- MENU ---\n\n");
          printf("1.\tCreate a new friend list\n");
          printf("2.\tExit o_O");
          printf("\n\n------------\n");
          printf("Go to:\t");
          choice = userChoice();
    
          switch (choice) {
              case 1: {
                  char name[NAME_SIZE] = "";
                  NodePointer head = NULL;
                  while(0 != strcmp(name, EXIT)){
                      printf("Enter new friend name or \"%s\" to return back to the main menu: ", EXIT);
                      scanf("%s", name);
                      if(0 != strcmp(name, EXIT)){
                          insertIntoLinkedList(name, &head);
                          displayNames(head);
                      }
                  }
                  displayNames(head);
                  break;
              }
              case 2: {
                  printf("\n\nYou have %d node(s) in your linked list. Have a great day.\n\n", nodeCounter);
                  break;
              }
              default:
                  printf("There is no such option. Please choose one of the option from 1 to 2.\n");
          }
      } while(choice != 2);
    
    
      return 0;
    }
    
    int userChoice() {
      int num;
      scanf("%d", &num);
      return num;
    }
    
    void insertIntoLinkedList(char word[], NodePointer *head){
      NodePointer newNode = NULL;
      NodePointer previous = NULL;
      NodePointer current = *head;
    
      newNode = malloc(sizeof(Node));
      if(NULL != newNode){
          strcpy(newNode -> name, word);
          while(NULL != current && strcmp(word, current -> name) > 0){
              previous = current;
              current = current -> next;
          }
    
          if(NULL == previous){
              newNode -> next = current;
              *head = newNode;
          } else {
              previous -> next = newNode;
              newNode -> next = current;
          }
      }
    }
    
    void displayNames(NodePointer current) {
      nodeCounter = 0;
      if(NULL == current){
          printf("Friend list is empty... I am sorry :(\n\n");
          return;
      } else {
          printf("\nCurrent friend list: ");
          while(NULL != current){
              nodeCounter++;
              printf("%s → ", current -> name);
              current = current -> next;
          }
          printf("\nNumber of friends in your current list:\t%d\n\n", nodeCounter);
      }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Rabbid76    6 年前

    一切正常,但是如果用户输入end并再次选择选项1,程序将创建一个新的链表,而我希望将名称添加到现有列表中。

    问题是您必须声明一个指针,该指针会将列表的头部划破 while 循环。

    NodePointer head = NULL; 
    do {
         ....
    
         switch (choice) {
         case 1: {
              char name[NAME_SIZE] = "";
              while(0 != strcmp(name, EXIT)){
    
                  ....
              }
         ....
         }
    } while(choice != 2);
    

    注意,您已经在 case . 看到了吗 Scope rules in C .
    在作用域的末尾,变量不再可访问,其内容也将丢失。下次“到达”代码时,将得到一个全新的初始化变量。

        2
  •  2
  •   Amcodes    6 年前

    你可以为它声明一个新函数。因为每次你调用这个函数,Head都会被重新声明。

    E.g case 3:printf("\nEnter A New Friend Name:\n");
           scanf("%s",name); 
           insertIntoLinkedList(name, &head);
           displayNames(head);
           break;