一个字符串错误和保存数据(带链表)
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();
}
}
};
这里有两个主要问题。
赋值不可逆...
在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
实例只包含垃圾值的原因...
混合使用 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) {}
我正在处理这个链表项目,我应该在这个项目中将员工数据保存在链表中并应用一些操作。 我是 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();
}
}
};
这里有两个主要问题。
赋值不可逆...
在
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
实例只包含垃圾值的原因...混合使用
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) {}