一个字符串错误和保存数据(带链表)

A string error and saving data (with linked list)

我正在处理这个链表项目,我应该在这个项目中将员工数据保存在链表中并应用一些操作。 我是 C++ 的新手,所以我会向您展示我的代码,请帮助我。 我的问题是:

1- 每当我输入全名时,程序就会无限循环!我使用了 getline() 方法,但仍然无法正常工作。但是如果我只输入名字就可以了。

2- 如果我使用我创建的方法给我随机数据,我不知道如何显示或查找员工信息。 我的代码:

主要内容:

#include<iostream>
#include<string>
#include <fstream>
#include "EmployeeList.cpp"
using namespace std;

int main(){
    string name;
    int choice, id;
    double Salary;
    EmployeeList* employee = new EmployeeList();

    cout<<"***********************************************"<<endl;
    cout<<"**********EMPLOYEE MANAGEMENT SYSTEM***********"<<endl;
    cout<<"***********************************************\n\n"<<endl;

    do{
        cout<<" 1--->Press 1 to INSERT EMPLOYMENT:"<<endl;
        cout<<" 2--->Press 2 to FIND EMPLOYMENT INFO ID:"<<endl;
        cout<<" 3--->Press 3 to DELETE EMPLOYMENT ID:"<<endl;
        cout<<" 4--->Press 4 to SEARCH HIGHEST SALARY:"<<endl;
        cout<<" 5--->Press 5 to DISPLAY ALL EMOLYMENTS:"<<endl;
        cout<<" 6--->Press 6 to REVERSE DISPLAY ALL EMPLOYMENTS:"<<endl;
        cout<<" 7--->Press 7 to EXIT:"<<endl;
        cout<<"\n Enter Your Choice: ";
        cin>>choice;

        switch(choice){
            case 1:
                cout<<endl;
                cout<<"Enter name : ";
                getline(cin,name);
                cout<<"Enter ID : ";
                cin>>id;
                cout<<"Enter Salary : ";
                cin>>Salary;
                cout<<endl;
                employee ->INSERTEMPLOYMENT(name,id,Salary);
            break;

            case 2:
                cout<<endl;
                cout<<"Enter ID : ";
                cin>>id;
                cout<<endl;
                employee->FINDEMPLOYMENTINFOID(id);
            break;

            case 3:
                cout<<endl;
                cout<<"Employee ID : ";
                cin>>id;
                cout<<endl;
                employee-> DELETEEMPLOYMENTID(id);
            break;

            case 4:
                cout<<endl;
                employee->SEARCHHIGHESTSALARY();
            break;

            case 5:
                cout<<endl;
                employee->DISPLAYALLEMPLOYMENTS();
            break;

            case 6:
                cout<<endl;
                employee->REVERSEDISPLAYALLEMPLOYMENTS(employee->getHead());
            break;

            case 7:
                exit(0);
            default:
                cout<<"Invalid choice."<<endl;
            break;
        }
    } while (true);


    return 0;
}

员工:

#include<iostream>
#include<stdlib.h>

using namespace std;

class Employee{
    private:
        string name;
        int ID;
        double Salary;
        Employee* next;

    public:
        //Constructor
        Employee (string n, int id, double s){
            n = name;
            id = ID;
            s = Salary;
            this->next = NULL;
        }

        //Setters
        void setName(string n){
            n = name;
        }
        void setID(int id){
            id = ID;
        }
        void setSalary(double s){
            s = Salary;
        }
        void setNext(Employee* next){
            this->next = next;
        }

        //Getters
        string getName(){
            return name;
        }

        int getID(){
            return ID;
        }

        double getSalary(){
            return Salary;
        }   
        Employee* getNext(){
            return this->next;
        }
};

员工名单:

#include "Employee.cpp"
using namespace std;

class EmployeeList{
    private:
        Employee* head;
    public:
    //Constructor
        EmployeeList(){         
            head = NULL;
        }
    //getter
        Employee* getHead(){
            return head;
        }

    //insert method 
        void INSERTEMPLOYMENT (string name, int id, double Salary){
            Employee* newnode = new Employee(name, id, Salary);
            if(head == NULL){
                head = newnode;
            } 
            else {
                Employee* temp = head;
                while(temp->getNext() != NULL){
                    temp = temp->getNext();
                }
                temp->setNext(newnode);
            }

            cout<<"The employee record was added successfully."<<endl;
            cout<<"------------------------------------------"<<endl;
        }

        //info
        void FINDEMPLOYMENTINFOID (int id){
            Employee *temp = head;
            bool status = false;
            while(temp != NULL){
                if(temp->getID() == id){
                    status = true;
                    cout<<"Employee Name = "<<temp->getName()<<endl;
                    cout<<"Employee ID = "<<temp->getID()<<endl;
                    cout<<"Employee Salary = "<<temp->getSalary()<<endl;
                    cout<<"---------------------------------------"<<endl;
                    }
                    temp = temp->getNext();
                }

            if(status == false) {
                cout<<"Employee is not found in the list."<<endl;
                cout<<"--------------------------------------------"<<endl;
                }
            }

        //display
        void DISPLAYALLEMPLOYMENTS (){
            Employee* temp = head;
            while(temp != NULL){
                cout<<"Employee Name = "<<temp->getName()<<endl;
                cout<<"Employee ID = "<<temp->getID()<<endl;
                cout<<"Employee Salary = "<<temp->getSalary()<<endl;
                cout<<"---------------------------------------"<<endl;
                temp = temp->getNext();
                }
            }

};

这里有两个主要问题。

  1. 赋值不可逆...

    Employee class 中,大多数赋值被颠倒了。构造函数是:

     //Constructor
     Employee (string n, int id, double s){
         n = name;     // replace the local copy of n with name!!!
         id = ID;
         s = Salary;
         this->next = NULL;
     }
    

    当然应该是:

     //Constructor
     Employee(string n, int id, double s) {
         name = n;
         ID = id;
         Salary= s;
         this->next = NULL;
     }
    

    这就是为什么您的 Employee 实例只包含垃圾值的原因...

  2. 混合使用 getline 和流提取器是危险的

    当您使用流提取器读取整数值时,流指针位于最后一个数字之后,即行尾之前。如果您在那之后立即使用 getline,您将只读取该换行符并得到一个空字符串。一个简单的技巧是始终跳过空行:

     case 1:
         cout << endl;
         cout << "Enter name : ";
         for (;;) {
             getline(cin, name);
             if (name != "") break;
         }
     ...
    

这应该足以解决眼前的问题。但其他人还在:

  • 您永远不会测试输入流的状态:如果用户输入了错误的数字,您将无法检测到它并且您的程序将出现错误行为

  • EmployeeList 作为一个链表应该表现为一个容器:它应该在它的析构函数中自动销毁它的元素。由于这一点和 5 的规则,它还应该有一个自定义的(或删除的)复制构造函数和复制赋值运算符。

  • 构造函数有一个特殊的语法来直接初始化它们的成员,而不是先默认初始化它们然后赋值给它们。它不仅效率稍高,而且是初始化 const 成员的唯一方法。因此,惯用的方式应该是:

      //Constructor
      Employee (string n, int id, double s)
              : name(n), ID(id), Salary(s), next(nullptr) {}