2015-04-28 51 views
1

我正在製作員工鏈接列表。做所有常見的事情,添加,搜索和更新。我試圖讓刪除功能正常工作,但在Node被刪除之後,我無法打印鏈接列表來查看。以下是完整的代碼以及錯誤消息。感謝您抽時間閱讀。在刪除節點後打印結構鏈表的錯誤

LinkedList.exe中的0x0FA4FB53(msvcr120d.dll)未處理的異常:0xC0000005:訪問衝突讀取位置0xFEEEFEEE。

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


#define ID_LENGTH 25 
#define NAME_LENGTH 25 
#define address_LENGTH 25 
#define department_LENGTH 25 
#define joinDate_LENGTH 25 
#define email_LENGTH 30 
int mymenu; 

//Create employee Structure 
typedef struct employee{ 
    char* ID; 
    char* name; 
    char* department; 
    char* address; 
    char* joinDate; 
    double salary; 
    char* email; 
    struct employee *next; 
}employee; 

//Declare Function Prototypes 
int login(); 
int Menu(); 
void Add(struct employee *head); 
void search(struct employee *head, char*); 
void update(struct employee *head, char*); 
void outputList(); 
struct employee* searchForEmployee(char*); 
employee* new_employee(char*, char*, char*, char*, char*, double, char*); 
employee* insert_by_employee(employee*, employee*); 
void removeEmployee(char *); 
void print_list(employee*); // prints out the LinkedList 


employee* head = NULL; 
employee* tail = NULL; 
employee* temp = NULL; 
employee* current = NULL; 


//this stores the employee that comes before the employee that is found by the searchforEmployee 
struct employee *empBeforeEmptoDelete = NULL; 

int main() { 
    int num = 0; 
    int MenuChoice = 0; 

    Menu(); 


    FILE *in; 
    char* ID = (char*)malloc(sizeof(char*) * ID_LENGTH); 
    char* name = (char*)malloc(sizeof(char*) * NAME_LENGTH); 
    char* department = (char*)malloc(sizeof(char*) * department_LENGTH); 
    char* address = (char*)malloc(sizeof(char*) * address_LENGTH); 
    char* joinDate = (char*)malloc(sizeof(char*) * joinDate_LENGTH); 
    double salary = 0; 
    char* email = (char*)malloc(sizeof(char*) * email_LENGTH); 


    if ((in = fopen("Employees.txt", "r")) == NULL) //Did the file successfully open? 
    { 
     printf("The input file failed to open.\n"); 
     printf("Program cannot continue. Exiting. . .\n"); 
     return 1; //Exit Program 
    } 


    while (!feof(in)) //Check for file end 
    { 
     //Read first data value to kickstart. 
     if (fscanf(in, "%s %s %s %s %s %lf %s", ID, name, department, address, joinDate, &salary, email) == EOF) { 
      break; 
     } 

     employee* hold = new_employee(ID, name, department, address, joinDate, salary, email); 
     head = insert_by_employee(head, hold); 

    } 

    //3. ------Print the new List------ 
    //print_list(head); 
    do 
    { 
     switch (MenuChoice = Menu()) 
     { 
     case 1: 
     { 
      Add(head); 
      break; 
     } 
     case 2: 
     { 
      char text[10]; 
      printf("Enter the text to search for :"); 
      scanf("%s", text); 
      //search(head, text); 
      searchForEmployee(text); 
      break; 
     } 
     case 3: 
     { 
      char text[10]; 
      printf("Enter the ID to update for :"); 
      scanf("%s", text); 
      update(head, text); 
      break; 
     } 
     case 4: 
     { 
      outputList(); 
      char text[10]; 
      printf("Enter the ID to remove :"); 
      scanf("%s", text); 
      removeEmployee(text); 
      outputList(); 
      break; 

     } 
     case 5: 
     { 
      print_list(head); 
      break; 
     } 
     case 6: 
     { 

      break; 
     } 
     case 7: 
     { 
      break; 
     } 
     case 8: 
     { 
      exit(0); 
      break; 
     } 
     default: 
     { 
      printf("\nInvalid Selection"); 
      break; 
     } 
     } 
    } while (MenuChoice < 8); 

    system("Pause"); 
    printf("\n\n\n"); 
    return 1; //Exit Success 
} 
employee* new_employee(char* id, char* name, char* department, char* address, char* joinDate, double salary, char* email) { 

    //Create new employee and malloc space 
    employee* new = (employee*)malloc(sizeof(struct employee)); 
    new->ID = (char*)malloc(sizeof(char) * ID_LENGTH); 
    new->name = (char*)malloc(sizeof(char) * NAME_LENGTH); 
    new->department = (char*)malloc(sizeof(char) * department_LENGTH); 
    new->address = (char*)malloc(sizeof(char) * address_LENGTH); 
    new->joinDate = (char*)malloc(sizeof(char) * joinDate_LENGTH); 
    new->email = (char*)malloc(sizeof(char) * email_LENGTH); 



    //Set data 
    strcpy(new->ID, id); 
    strcpy(new->name, name); 
    strcpy(new->department, department); 
    strcpy(new->address, address); 
    strcpy(new->joinDate, joinDate); 
    new->salary = salary; 
    strcpy(new->email, email); 
    //Retun a pointer to the node 
    return new; 

} 

//Inserts new node into an alphabetically sorted linked list. 
employee* insert_by_employee(employee* head, employee* new) 
{ 
    employee* current = NULL; 
    current = head; 
    if (current == NULL || strcmp(current->department, new->department) > 0) 
    { 
     new->next = current; 
     return new; 
    } 
    else { 

     while (current->next != NULL && strcmp(current->next->department, new->department) < 0) 
     { 

      current = current->next; 
     } 
    } 
    new->next = current->next; 
    current->next = new; 
    return head; 

} 
struct employee* searchForEmployee(char* id){ 
    struct employee *empIterator = head; 
    char i[] = "Employee ID"; 
    char n[] = "Name"; 
    char a[] = "Address"; 
    char d[] = "Department"; 
    char jd[] = "Join Date"; 
    char s[] = "Salary"; 
    char em[] = "Email"; 

    while (empIterator != NULL){ 
     int isEqual = strcmp(empIterator->ID, id);//if the passed in ID is equla to the ID of the node then isEqual will ring true 

     if (!isEqual){ 

      printf("Employee Found\n"); 
      printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
      printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", empIterator->ID, empIterator->name, empIterator->address, empIterator->department, empIterator->joinDate, empIterator->salary, empIterator->email); 
      //printing out the current node which is the desired employee 
      printf("-----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
      return empIterator; 
     } 
     empBeforeEmptoDelete = empIterator->next; 

     empIterator = empIterator->next; 
    } 
    printf("%s was not found\n\n", id); 
    return NULL; 
} 
void print_list(employee* head) 
{ 
    employee* current; 
    current = head; 
    char i[] = "Employee ID"; 
    char n[] = "Name"; 
    char a[] = "Address"; 
    char d[] = "Department"; 
    char jd[] = "Join Date"; 
    char s[] = "Salary"; 
    char em[] = "Email"; 


    //Header 
    printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em); 
    printf("--------------------------------------------------------------------------------------------------------------------------------------------\n"); 


    while (current != NULL) 
    { 
     printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", current->ID, current->name, current->address, current->department, current->joinDate, current->salary, current->email); 
     current = current->next; 
    } 
    printf("-------------------------------------------------------------------------------------------------------------------------------------------\n"); 


    return; 
} 
int login() 
{ 

    char username[7]; 
    char password[7]; 

    printf("\nPlease enter your Username: "); 
    scanf("%s", username); 
    printf("\nPlease enter your Password: "); 
    scanf("%s", password); 

    struct login{ 
     char name[7]; 
     char password[7]; 

    }; 
    struct login details[3]; 
    fflush(stdin); 

    FILE *file; 
    file = fopen("login.txt", "r"); 
    if (file == NULL){ 
     printf("Can not open the file\n"); 
     exit(-1); 
    } 
    fflush(stdin); 

    for (int i = 0; i < 3; i++){ 
     fscanf(file, "%s %s\n", details[i].name, details[i].password); 
    } 


    for (int i = 0; i < 3; i++){ 
     if ((strcmp(details[i].name, username) == 0) && (strcmp(details[i].password, password) == 0)) 
     { 
      printf("\nWelcome "); 
      Menu(); 
     } 
     fflush(stdin); 
    } 
} 
int Menu() 
{ 
    int Choice = 0; 

    do{ 

     printf("1. Add\n"); 
     printf("2. Show\n"); 
     printf("3. Update\n"); 
     printf("4. Delete\n"); // Write a Function for this 
     printf("5. Departments\n"); 
     printf("6. Employee Report\n"); 
     printf("7. \n"); 
     printf("8. Exit\n\n\n\t\tSELECTION = "); 

     fflush(stdin); 

     scanf("%d", &Choice); 
     fflush(stdin); 
    } while (Choice < 0 || Choice > 8); 

    return(Choice); 
} 
void Add() 
{ 

    char* ID = (char*)malloc(sizeof(char*) * ID_LENGTH); 
    char* name = (char*)malloc(sizeof(char*) * NAME_LENGTH); 
    char* department = (char*)malloc(sizeof(char*) * department_LENGTH); 
    char* address = (char*)malloc(sizeof(char*) * address_LENGTH); 
    char* joinDate = (char*)malloc(sizeof(char*) * joinDate_LENGTH); 
    double salary = 0; 
    char* email = (char*)malloc(sizeof(char*) * email_LENGTH); 


    printf("\nEnter the ID : "); 
    scanf("%s", ID); 
    printf("\nEnter the new employee name : "); 
    scanf("%s", name); 
    printf("\nEnter their address : "); 
    scanf("%s", address); 
    printf("\nEnter their department : "); 
    scanf("%s", department); 
    printf("\nEnter their start date : "); 
    scanf("%s", joinDate); 
    printf("\nEnter their salary : "); 
    scanf("%lf", &salary); 
    printf("\nEnter their email : "); 
    scanf("%s", email); 


    employee* hold = new_employee(ID, name, department, address, joinDate, salary, email); 
    head = insert_by_employee(head, hold); 
} 
void search(struct employee *head, char *crit)//This function takes in the head pointer and a character array pointer 
{ 
    int choice;//menu choice tracker 

    //arrays to hold the header heads 
    char i[] = "Employee ID"; 
    char n[] = "Name"; 
    char a[] = "Address"; 
    char d[] = "Department"; 
    char jd[] = "Join Date"; 
    char s[] = "Salary"; 
    char em[] = "Email"; 

    //sub menu to filter by ID and Name searches 
    printf("\nSearch by "); 
    printf("\n1 : ID"); 
    printf("\n2 : Name\n"); 
    scanf("%d", &choice); 

    //if the user wants to search by ID 
    if (choice == 1){ 
     while (head != NULL) 
     { 
      //compare the ID to the criteria. If its the same then execute this if 
      if ((strcmp(head->ID, crit) == 0)) 
      { 
       //print that we found the employee 
       printf("Employee Found\n"); 
       printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
       printf("----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", head->ID, head->name, head->address, head->department, head->joinDate, head->salary, head->email); 
       //printing out the current node which is the desired employee 
       printf("-----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       return; 
      } 
      head = head->next;//increments the node until we get to the end of the Linked List 
     } 
     printf("Employee not found\n");//Else there is no Employee with an ID of the entered criteria 
    } 
    //if the user wants to search by Name 
    else if (choice == 2){ 
     while (head != NULL) 
     { 
      //compare the Name to the criteria. If its the same then execute this if 
      if ((strcmp(head->name, crit) == 0)) 
      { 
       //print that we found the employee 
       printf("Employee Found\n"); 
       printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
       printf("----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", head->ID, head->name, head->address, head->department, head->joinDate, head->salary, head->email); 
       //printing out the current node which is the desired employee 
       printf("----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       return; 
      } 
      head = head->next;//increments the node until we get to the end of the Linked List 
     } 
     printf("Employee not found\n");//Else there is no Employee with an Name of the entered criteria 
    } 
    else 
     printf("Bad input");//Otherwise the user entered a choice out of the range of our handled input 
} 
void update(struct employee *head, char *crit)//This function takes in the head pointer and a character array pointer 
{ 


    //arrays to hold the header heads 
    char i[] = "Employee ID"; 
    char n[] = "Name"; 
    char a[] = "Address"; 
    char d[] = "Department"; 
    char jd[] = "Join Date"; 
    char s[] = "Salary"; 
    char em[] = "Email"; 

    char id[25]; 
    char name[25]; 
    char address[25]; 
    char department[25]; 
    char joinDate[25]; 
    double salary; 
    char email[25]; 


    //if the user wants to search by ID 
     while (head != NULL) 
     { 
      //compare the ID to the criteria. If its the same then execute this if 
      if ((strcmp(head->ID, crit) == 0)) 
      { 
       //print that we found the employee 
       printf("Employee Found\n"); 
       printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
       printf("----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", head->ID, head->name, head->address, head->department, head->joinDate, head->salary, head->email); 
       //printing out the current node which is the desired employee 
       printf("-----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 

       printf("\nEnter the ID : "); 
       scanf("%s", id); 
       printf("\nEnter the new employee name : "); 
       scanf("%s", name); 
       printf("\nEnter their address : "); 
       scanf("%s", address); 
       printf("\nEnter their department : "); 
       scanf("%s", department); 
       printf("\nEnter their start date : "); 
       scanf("%s", joinDate); 
       printf("\nEnter their salary : "); 
       scanf("%lf", &salary); 
       printf("\nEnter their email : "); 
       scanf("%s", email); 

       strcpy(head->ID, id); 
       strcpy(head->name, name); 
       strcpy(head->department, department); 
       strcpy(head->address, address); 
       strcpy(head->joinDate, joinDate); 
       head->salary = salary; 
       strcpy(head->email, email); 

       printf("Employee Found\n"); 
       printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
       printf("----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 
       printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", head->ID, head->name, head->address, head->department, head->joinDate, head->salary, head->email); 
       //printing out the current node which is the desired employee 
       printf("-----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 

       return; 
      } 
      head = head->next;//increments the node until we get to the end of the Linked List 
     } 
     printf("Employee not found\n");//Else there is no Employee with an ID of the entered criteria 
    } 
void outputList(){ 
    char i[] = "Employee ID"; 
    char n[] = "Name"; 
    char a[] = "Address"; 
    char d[] = "Department"; 
    char jd[] = "Join Date"; 
    char s[] = "Salary"; 
    char em[] = "Email"; 

    struct employee * employees = head; 
    printf("Employees Entered\n\n"); 
    while (employees != NULL){ 
     printf("Employee Found\n"); 
     printf("\n\n|%15s | %15s | %15s | %15s | %15s| %15s | %15s|\n", i, n, a, d, jd, s, em);//header formatting 
     printf("|%15s | %15s | %15s |%15s | %15s | %15.2lf| %25s\n", employees->ID, employees->name, employees->address, employees->department, employees->joinDate, employees->salary, employees->email); 
     printf("-----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 

     employees = employees->next; 
    } 
} 
void removeEmployee(char* empID){ 

    struct employee* empToDelete = NULL; 

    empToDelete = searchForEmployee(empID); 

    if (empToDelete != NULL){ 

     printf("%s was deleted\n\n", empID); 

     if (empToDelete == head){ 

      head = empToDelete->next; 
     } 
     else{ 
      empBeforeEmptoDelete->next = empToDelete->next; 
     } 

     free(empToDelete); 
    } 
    else{ 
     printf("%s was not found", empID); 
    } 
} 

回答

1
removeEmployee(char* empID)功能


情況下:當節點要被刪除不是頭節點;

這裏,首先你要保存的delete_nodeprevious_node的指針,然後設置previous_node->nextdelete_node->next並刪除delete_node

您還沒有保存previous_node的指針。

empBeforeEmptoDelete->next = empToDelete->next; 
1

問題是與

empBeforeEmptoDelete = empIterator->next; 
empIterator = empIterator->next; 

所以empBeforeEmptoDelete點之前的記錄。更改爲

empBeforeEmptoDelete = empIterator; 
empIterator = empIterator->next;