2015-02-09 99 views
0

,我也從一個文本文件閱讀:打破這個while循環的

George Washington, 2345678 
John Adams, 3456789 
Thomas Jefferson, 4567890 
James Madison, 0987654 
James Monroe, 9876543 
John Quincy Adams, 8765432 
Andrew Jackson, 7654321 
Martin Van Buren,
William Henry Harrison,9 
John Tyler,98 

刪除工程爲名的功能,但是當它是成功的printf語句只是繼續循環的命令窗口。我試圖在循環結尾使用break語句,但是這隻會導致沒有找到該名稱。有人可以提供任何見解嗎?

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

//Creates node for holding student's information 
struct node 
{ 
    char name [50]; 
    int id; 
    struct node *next; 
}*head; 

//Create Function Prototypes 
void readDataFile(); 
void insert(char *inName, char *inID); 
void display(struct node *d); 
int deleteID(int num); 
void deleteName(char *delete_name); 


//Main function 
int main() 
{ 
    //Declare variables 
    int i, num, delete_id, id; 
    char *name; 
    char nameDelete [50]; 
    char nameInsert [50]; 
    struct node *n; 

    //initialize link list 
    head = NULL; 

    //Read in file 
    readDataFile(); 

    //Create list of operations utilized in program 
    while (1) 
    { 
     printf("\nList Operations\n"); 
     printf("===============\n"); 
     printf("1.Insert\n"); 
     printf("2.Display\n"); 
     printf("3.Delete by ID\n"); 
     printf("4.Delete by Name\n"); 
     printf("5.Exit\n"); 
     printf("Enter your choice : "); 

     if(scanf("%d", &i) <= 0) 
     { 
      printf("Enter only an Integer\n"); 
      exit(0); 
     } 
     else 
     { 
      switch(i) 
      { 
       case 1: 
        getchar(); 
        printf("Enter the name to insert:"); 
        scanf("%[^\n]s", nameInsert); 
        printf("\nEnter the ID associated with the name: "); 
        scanf("%d", &id); 
        break; 
       case 2: 
        if (head == NULL) 
         printf("List is Empty\n"); 
        else 
        { 
         printf("Elements in the list are:\n"); 
        } 
        display(n); 
        break; 
       case 3: 
        if(head == NULL) 
         printf("List is Empty\n"); 
        else 
        { 
         printf("Enter the ID number to delete: "); 
         scanf("%d", &delete_id); 
        } 

        if(deleteID(delete_id)) 
         printf("%d deleted successfully \n", delete_id); 
        else 
         printf("%d not found in the list\n", delete_id); 
        break; 
       case 4: 
        getchar(); 
        if(head == NULL) 
         printf("List is Empty\n"); 
        else 
        { 
         printf("Enter name to delete: "); 
         scanf("%[^\n]s", nameDelete); 
         printf("Checking for name %s...\n", nameDelete); 
         printf("%s not found in the list\n", nameDelete); 
         deleteName(nameDelete); 
        } 
        break; 
       case 5: 
        return 0; 
       default: 
        printf("Invalid option\n"); 
      } 
     } 
    } 
    return 0; 
} 

//Define the functions 
//Function to delete by name 
void deleteName(char *delete_name) 
{ 
    //Create temporary and helper node 
    struct node *temp, *helper; 

    //Set temp equal to head 
    temp = head; 

    //Loop until the end of the list 
    while(temp != NULL) 
    { 
     if(strcmp(temp->name, delete_name) == 0) 
     { 
      if(temp == head) 
      { 
       head = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
      else 
      { 
       helper->next = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
     } 
     else 
     { 
      helper = temp; 
      temp = temp->next; 
     } 
    } 
break; 
} 
+1

爲什麼在'while'循環內的'if(temp == head){...} else {...}'語句之後不要簡單地使用'break;'(或'return;')在'deleteName()'中? – 2015-02-09 02:40:30

+1

問題在於while循環條件。 temp可能不會到達鏈表的末尾。更正以匹配邏輯 – 2015-02-09 02:41:35

+1

您能否註釋您嘗試放置「break」的位置?如果沒有這個,就很難看出你爲什麼出錯了。 – aruisdante 2015-02-09 02:41:36

回答

2

請學習如何讓一個MCVE(How to create a Minimal, Complete, and Verifiable Example?)或SSCCE(Short, Self-Contained, Correct Example) - 兩個名稱和鏈接爲相同的基本思想。

這是從您的代碼派生的MCVE。我在deleteName()的循環中添加了缺少的break;return;。我改寫了main()基本上完全,但它的作品乾淨:

#include <assert.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct node 
{ 
    char name[50]; 
    int id; 
    struct node *next; 
} *head; 

void deleteName(char *delete_name); 

int main(void) 
{ 
    struct node *n; 

    head = NULL; 

    head = malloc(sizeof(*head)); 
    assert(head != 0); 
    strcpy(head->name, "Abraham Lincoln"); 
    head->id = 1; 
    head->next = 0; 

    n = malloc(sizeof(*n)); 
    strcpy(n->name, "George Washington"); 
    n->id = 2; 
    n->next = head; 
    head = n; 

    n = malloc(sizeof(*n)); 
    strcpy(n->name, "John Adams"); 
    n->id = 3; 
    n->next = head; 
    head = n; 

    deleteName("George Washington"); 
    deleteName("John Adams"); 
    deleteName("Abraham Lincoln"); 

    return 0; 
} 

void deleteName(char *delete_name) 
{ 
    struct node *temp, *helper = 0; 

    temp = head; 

    while (temp != NULL) 
    { 
     if (strcmp(temp->name, delete_name) == 0) 
     { 
      if (temp == head) 
      { 
       head = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
      else 
      { 
       helper->next = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
      return; // The key change! 
     } 
     else 
     { 
      helper = temp; 
      temp = temp->next; 
     } 
    } 
} 

了清晰跑下valgrind和Mac OS X 10.10.2與GCC 4.9.1。

Found George Washington! 
George Washington deleted successfully 
Found John Adams! 
John Adams deleted successfully 
Found Abraham Lincoln! 
Abraham Lincoln deleted successfully 

重要的是要學習如何殘酷有關創建MCVE時剝離不相關的代碼是很重要的。

0

break關鍵字將跳出最近的開關或迴路。因此,你可以試試這個:

while(temp != NULL) 
{ 
    if(strcmp(temp->name, delete_name) == 0) 
    { 
     if(temp == head) 
     { 
      head = temp->next; 
      free(temp); 
      printf("Found %s!\n", delete_name); 
      printf("%s deleted successfully\n", delete_name); 
      break; 
     } 
     else 
     { 
      helper->next = temp->next; 
      free(temp); 
      printf("Found %s!\n", delete_name); 
      printf("%s deleted successfully\n", delete_name); 
      break; 
     } 
    } 
    else 
    { 
     helper = temp; 
     temp = temp->next; 
    } 
} 

另一種解決方案是你釋放後,設置溫度爲NULL(這是很好的做法,無論如何,所以這可能是另一種想法)

0

在IF塊的末尾添加return語句,一旦你找到要刪除

void deleteName(char *delete_name) 
{ 
    //Create temporary and helper node 
    struct node *temp, *helper; 

    //Set temp equal to head 
    temp = head; 

    //Loop until the end of the list 
    while(temp != NULL) 
    { 
     if(strcmp(temp->name, delete_name) == 0) 
     { 
      if(temp == head) 
      { 
       head = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
      else 
      { 
       helper->next = temp->next; 
       free(temp); 
       printf("Found %s!\n", delete_name); 
       printf("%s deleted successfully\n", delete_name); 
      } 
      return; 
     } 
     else 
     { 
      helper = temp; 
      temp = temp->next; 
     } 
    } 
} 

而且你如何計劃,以表明名稱不是列表的一部分的名字,反對被發現和刪除。您可以更改修改函數,使其在列表中未找到名稱時返回錯誤代碼,然後用該名稱指示名稱從未在列表中開始。

0
I did not really look at the delete() function, 
however, the following code illustrates how the 
code should be formatted, etc. 

notice the checking for input errors, which should always be performed 
notice the separation of the struct definition from the struct declaration 
notice the easy readability of the switch cases 
    by incorporating some vertical white space 
notice the simple comments after the closing braces 
notice that no call to an action is performed if the linked list is empty 



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

//define node for holding student's information 
struct node 
{ 
    char name [50]; 
    int id; 
    struct node *next; 
}; 

// create head pointer for linked list of student info 
// and initialize 
struct node *head = NULL; 

// Function Prototypes 
// note: if all these functions are only accessed within this file 
//  then they should be declared with the 'static' modifier 
void readDataFile (void); 
void insert (char *inName, char *inID); 
void display (struct node *d); 
void deleteID (int delete_ID); 
void deleteName (char *delete_name); 


//Main function 
int main() 
{ 
    //Declare local variables 
    // notice use of meaningful names 
    // notice, for readability and documentation, 
    //   only one variable declared per line 
    int i; // receives user menu selection input 
    int idDelete; 
    int idInsert; 
    char nameDelete [50]; 
    char nameInsert [50]; 
    // struct node *n; // unused variable 
    int done = 0; // used to exit when user enters '5' 



    //Read in file 
    readDataFile(); 

    //Create list of operations utilized in program 
    while (!done) 
    { 
     printf("\nList Operations\n"); 
     printf("===============\n"); 
     printf("1.Insert\n"); 
     printf("2.Display\n"); 
     printf("3.Delete by ID\n"); 
     printf("4.Delete by Name\n"); 
     printf("5.Exit\n"); 
     printf("Enter your choice : "); 

     if(1 != scanf("%d", &i)) 
     { // then, scanf failed 
      perror("scanf for choice failed"); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, scanf successful 

     switch(i) 
     { 
      case 1: 
       int ch; 
       while(EOF != (ch = getchar()) && (ch != '\n')); 

       printf("Enter the name to insert:"); 

       if(1 != (scanf("%[^\n]s", nameInsert))) 
       { // then scanf failed 
        perror("scanf for new student name failed"); 
        exit(EXIT_FAILURE); 
       } 

       // implied else, scanf successful 

       printf("\nEnter the ID associated with the name: "); 

       if(1 != (scanf("%d", &idInsert))) 
       { // then scanf failed 
        perror("scanf for new student ID failed"); 
        exit(EXIT_FAILURE); 
       } 

       // implied else, scanf successful 

       insert(nameInsert, idInsert); 
       break; 

      case 2: 
       if (head == NULL) 
        printf("List is Empty\n"); 
       else 
       { 
        printf("Elements in the list are:\n"); 
        display(n); 
       } // end if 
       break; 

      case 3: 
       if(head == NULL) 
        printf("List is Empty\n"); 
       else 
       { 
        printf("Enter the ID number to delete: "); 

        if(1 != (scanf("%d", &idDelete))) 
        { // then, scanf failed 
         perror("scanf for ID to delete failed"); 
         exit(EXIT_FAILURE); 
        } 

        // implied else, scanf successful 

        deleteID(idDelete); 
       } // end if 
       break; 

      case 4: 
       int ch; 
       while(EOF != (ch = getchar()) && (ch != '\n')); 

       if(head == NULL) 
        printf("List is Empty\n"); 
       else 
       { 
        printf("Enter name to delete: "); 

        if(1 != (scanf("%[^\n]s", nameDelete))) 
        { // then, scanf failed 
         perror("scanf for name to delete failed"); 
         exit(EXIT_FAILURE); 
        } 

        // implied else, scanf successful 

        printf("Checking for name %s...\n", nameDelete); 

        deleteName(nameDelete); 
       } // end if 
       break; 

      case 5: 
       done = 1; // this will cause while() loop to exit 
       break; 

      default: 
       printf("Invalid option\n"); 
       break; 
     } // end switch 
    } // end while 
    return 0; 
} // end of function: main