数据结构课程设计-职工管理系统

 《数据结构》课程设计报告
 
 
设计题目    简单的职工管理系统      
       计算机科学与技术          
       06教育班                        
                                               
                                              
完成日期    2008-06-1                   
 
 
        


       
 
 
1. 问题描述………………………………………………1
2. 系统设计………………………………………………1
3. 数据结构与算法描述…………………………………4
4. 测试结果与分析………………………………………9
5. 总 结…………………………………………………14
6. 参考文献……………………………………………17
附录 程序源代码………………………………………17
 


简单的职工管理系统
1. 问题描述
对单位的职工进行管理,包括插入、修改、删除、查找等功能。
2. 系统设计
2.1 设计目标
职工对象包括姓名、性别、年龄、出生年月、工作年月、学历、职务、住址、电话等信息。在此基础上实现增加、删除、查询、修改等操作。
2.2 设计思想
一个简单的职工管理系统,根据要求作如下设计:
2.2.1首先主要设计定义了两个类:
员工信息管理类:主要用于对员工信息进行新增、查询、修改、删除等操作处理。主要包括以下几种信息处理函数:
     void NewInfo(); //添加新成员函数
    void ShowInfo(); //员工信息查询函数
    void showall(); //全体员工输出函数
    void showdegree(int degree); //按学历输出函数
    void showage(int min,int max); //按年龄段输出函数
    void shownum(long number); //按编号输出函数
    void RefreshInfo(); //修改员工信息函数  
    void DeleteInfonum(int cNum);//按编号删除员工数据函数
    void DeleteInfodegree(int degree);//按学历删除员工数据函数
    void DeleteInfoname(string name);//按姓名删除员工数据函数
    void DeleteInfoall(); //删除所有员工信息函数
    void DeleteInfo(); //删除员工信息函数
    static int MaxNum();//返回系统已存储人数函数
文件操作类:主要用于对员工信息处理过程中对文件读入、写出等操作。主要包括以下两种处理函数:
    void WriteIn(int iflag); //数据写入操作函数
   void ReadOut(); //数据读出操作函数
void RefreshMaxNum(int iflag); //更新系统中员工计数文件函数
对于员工信息的保存,由写入函数writein(int iflag)写入文件Employee.txt中,并将员工总人数写入文件EmployeeMaxNum.txt 中。
当需要读出时,由读出函数readout();读出,注意读出时保存顺序与写入时的数据保存顺序要一致。
然后对类的成员函数进行具体定义。
2.2.2新增员工数据功能的设计
由员工信息管理类成员函数[void Employee::NewInfo();]完成。首先读取文件中的员工信息,根据已有信息设置编号,编号的设置方法为:若无保存数据,则第一个的编号设为1001,否则根据最后一个员工的编号加一,以达到编号递增排序。然后进行数据输入,结束后由写入函数将数据写入到文件,提示新增成功。
2.2.3查询员工数据功能的设计
查询功能设计了四种查询方法:输出所有[showall()]、按学历输出[showdegree(int degree)]、按年龄段输出[showage(int min,max)]以及按编号输出[shownum(int number)]。前三种方法都是基于按编号输出来实现,即需要调用按编号输出函数shownum(int number);。
按编号输出函数,根据参数形参number遍历已有数据(条件:Enum == number),找到该编号则输出其信息,否则提示未找到相关信息。
另外三种查询方式都是先根据输入的数据查找相应的编号,然后将该编号传递给[shownum()]函数进行显示输出。
设计一个输出信息函数[showinfo()]进行设计一个选择菜单,根据选择不同的操作调用相应的函数执行。
2.2.4修改员工数据功能的设计
由员工信息管理类成员函数[Employee::RefreshInfo()]完成。要求输入编号进行修改。首先读取文件保存的员工信息,然后要求输入要修改的员工编号,如果找到该编号信息,则输出信息,并提示是否修改,选择是则进行修改,然后保存信息提示修改成功。否则提示未找到返回主菜单。
2.2.5删除员工数据功能的设计
删除功能设计了四种删除方法:
按编号删除[Employee::DeleteInfonum(int cNum)]
按学历删除[Employee::DeleteInfodegree(int degree)]
按姓名删除[Employee::DeleteInfoname(string name)]
删除所有[Employee::DeleteInfoall()]
删除方法基本相似,先读取文件保存的内容,然后根据传递给函数的形参进行查找相关信息,找到则输出信息并提示是否删除,选择是则删除操作并提示删除成功。未找到则提示未找到相关信息。但每个函数的设计还是有很多区别的。
设计了一个删除函数[Employee::DeleteInfo()],进行设计一个选择菜单,根据选择不同的删除方法调用相应的函数执行。
2.2.6主程序的设计
主程序开始,设计一个选择菜单,根据选择进行调用信息管理类的不同的成员函数实现相应的操作。
2.3 系统模块划分
2.3.1本程序共分为以下几个主要模块:
新建员工数据
查询员工数据
修改员工数据
删除员工数据
2.3.2员工信息的主要内容 如表2-3-2
2-3-2员工信息表
列名
数据类型
姓名
string
编号
Int
性别
char
年龄
Int
出生年月
string
工作年月
string
学历
Int
职位
Int
住址
String
电话
String
3. 数据结构与算法描述
3.1程序的数据结构
3.1.1定义全局变量与函数
const N=50; //定义系统可录入的员工最大数值
string Ename[N]; //姓名
long Enum[N];     //人数
char Esex[N];     //性别
int Eage[N];      //年龄
string Eborndate[N]; //出生年月
string Eworkdate[N]; //工作年月
int Edegree[N]; //学历
int Eposition[N]; //职位
string Eaddress[N]; //住址
string Ephone[N];   //电话
int shuzi(int sz);//数字判断函数 也可用void shuzi(int& sz);方式
3.1.2定义员工管理类
用于程序运行中对员工信息进行各种操作
class Employee{
public:
    string Employeename; //姓名
    long Employeenum; //人数
    char Employeesex; //性别
    int Employeeage; //年龄
    string Employeeborndate; //出生年月
    string Employeeworkdate; //工作年月
    int Employeedegree;     //学历
    int Employeeposition;   //职位
    string Employeeaddress; //住址
    string Employeephone;   //电话
    static long EmployeeMaxNum;//静态变量,主要用于对编号的处理
    void NewInfo(); //添加新成员函数
    void ShowInfo(); //员工信息查询函数
    void showall(); //全体员工输出函数
    void showdegree(int degree); //按学历输出函数
    void showage(int min,int max); //按年龄段输出函数
    void shownum(long number); //按编号输出函数
    void RefreshInfo(); //修改员工信息函数  
    void DeleteInfonum(int cNum);//按编号删除员工数据函数
    void DeleteInfodegree(int degree);//按学历删除员工数据函数
    void DeleteInfoname(string name);//按姓名删除员工数据函数
    void DeleteInfoall(); //删除所有员工信息函数
    void DeleteInfo(); //删除员工信息函数
    static int MaxNum();//返回系统已存储人数函数
};
3.1.3定义文件操作类
主要用于程序运行中对员工信息进行文件读入、写出等操作
class DBOperate{
public:
    string Employeename;
    long Employeenum;
    char Employeesex;
    int Employeeage;
    string Employeeborndate;
    string Employeeworkdate;
    int Employeedegree;
    int Employeeposition;
    string Employeeaddress;
string Employeephone;
static long EmployeeMaxNum;
    void WriteIn(int iflag); //数据写入操作函数
    void ReadOut(); //数据读出操作函数
    void RefreshMaxNum(int iflag); //更新系统中员工计数文件函数
};
3.1.4所有函数定义
对定义的函数进行具体定义实现
3.1.5主函数的定义
int main(){
    system("color 06f"); //设置当前窗口的背景色和前景色
    char* select;
    select=new char;
    while(*select!='5'){
       do{
cout<<"t===================主菜单===================="<<endl;
cout<<"t     请选择功能"<<endl;
cout<<"t———————————————"<<endl;
cout<<"t         1.新建并输入职工数据"<<endl;
cout<<"t         2.按条件输出职工数据"<<endl;
cout<<"t         3.修改指定职工的数据"<<endl;
cout<<"t         4.删除数据"<<endl;
cout<<"t         5.退出"<<endl;
cout<<"t============================================="<<endl;
cout<<"t———————————————"<<endl;
cout<<" 请选择您要服务的类别: " ;
cin>>select;
cout<<"n============================================n";
           Employee e;
           DBOperate dbo;
           switch(*select){
           case '1': e.NewInfo(); break;
           case '2':
              dbo.ReadOut();
              e.ShowInfo(); break;
           case '3': e.RefreshInfo(); break;
           case '4': e.DeleteInfo(); break;
           case '5': sign();break;
           default:cout<<"输入错误,请重新输入!"<<endl;
           }
           cout<<endl<<endl;
       }while(*select<'1'||*select>'5');
    }
    exit(1);
    return 0;
}
3.1.6整体设计结构设计图 
 


3.1.7程序流程图
 
4. 测试结果与分析
4.1测试结果示例
4.1.1程序开始,显示主菜单:
4.1.2新建员工数据
选择1,新建员工数据:
4.1.3查询员工数据
添加完后返回主菜单。选择 2,按条件输出职工信息,实现的是查询功能:
可以选择4 种查询输出方式:
a.输出全体职工信息,输出一个暂停一下,回车后继续,直至全部输出:
 
b.选择按职工学历输出,则要求选择学历,然后输出所有同学历的职工信息,同样输出一位暂停一下直至全部输出后返回主菜单:
 
c.选择按年龄段输出,则输出所有在这个年龄段范围内的职工信息:
d.选择按职工编号输出,则输出所输入编号职工的信息,如果编号输入错误则提示未找到相关信息:
 
 
4.1.4修改员工数据
选择 3,则修改指定编号员工的信息,如果输入编号不存在则提示未找到相关信息,如找到,则先显示该信息,提示是否修改:
4.1.5删除员工数据
选择 4,则对员工信息进行删除操作,共有四种删除方式供选择:
a.选择1 按编号删除,要求输入要删除的编号,如果输入编号不存在则提示未找到相关信息,否则显示该编号员工的信息,并提示是否删除。选择Y,则进行删除并提示删除成功,否则返回主菜单:
b.选择 2 按学历进行删除,则先要求选择要删除的学历,如果找到相关信息,然后显示该学历的所有员工信息,并提示是否删除。否则返回主程序:
c.选择 3 按姓名进行删除,则输入姓名后进行查找,如找到则显示信息,进行逐条提示删除,直至所有该姓名的员工均查找出来;否则提示未找到相关信息,并返回主菜单:
输入错误提示未找到:
d.选择 4 全部删除,则提示是否删除:
 
4.1.6结束界面
 选择 5,程序结束,显示程序结束的签名界面然后退出:
5. 总 结
5.1 遇到的问题及解决方法
本程序考虑了程序功能实现、格式显示合理化、输入错误异常处理等各个方面的设计,尽可能使程序设计的更加完美。在长期的设计调试过程中遇到过许多问题,通过网上搜索、查询资料、调试试验等方法一一解决。下面大致罗列一些主要问题:
5.1.1关于输入错误的异常处理:数字判断
在调试程序过程中我们都知道在要求输入整型数据时,如不小心键入字母符号等,则程序立即出错;还有如在要求输入一个字符时,如果不小心输入为了字符串,则也会出错(此时多键入的字符被保留在缓冲区内,当下次要求屏幕输入时先从缓冲区取出导致出错)。因此设计了一个判断函数int shuzi(int n); 进行处理此类输入异常错误。此函数主要设计思路为:定义一个动态字符串指针,输入后判断每个输入的字符是否在’0’—‘9’ 之间来判断是否输入的为数字字符,然后按照字符ASCII码值与数字值的关系将输入的字符转换为整数。
而对于字符输入的问题,可以定义为一个动态字符串指针然后只取输入的第一个字符内容。
5.1.2关于某些系统函数调用时的执行顺序:
        在调用一些系统函数如getch() system("pause")等时发现其执行顺序的一些问题。如类似:
cout<<" =================================="<<endl;
cout<<" nnn"<<endl;
system("pause");//暂停
调试时发现此时:在Microsoft Visual C++ 6.0中先执行system("pause") 再输出显示,而在调试器Bloodshed Dev-C++中则顺序执行;但当把cout<<" nnn"<<endl; 改为 cout<<endl<<endl<<endl; 其他不变时,则在两中调试器中均为顺序执行,即先显示后暂停。
查找了一下相关帮助:
     OSTREAM.H中有这样的一个inline函数:
     inline _CRTIMP ostream& __cdecl endl(ostream& _outs) { return _outs << 'n' << flush; }
     也就是说
     endl= return _outs << 'n' << flush;
     endl除了写'n'进外,还调用flush函数,刷新缓冲区,把缓冲区里的数据写入文件或屏幕。如果考虑效率就用'n'
5.1.3关于设置暂停的方法:
      在有些地方需要暂停一下以便于用户查看信息等,总结了下大致可用以下几中方法:
方法一:
#include <stdlib.h>
system("pause");//
暂停一下并显示“输入任意键继续
方法二:
#include <stdio.h>
getchar();//
须按回车键结束,不是任意键
方法三:
#include <conio.h>
getch();//
等待键盘输入,不返回任何值,无任何显示
方法四:
使用 char* tt=new char; cin>>tt; 方式要求键盘输入一与程序无关的变量
5.1.4关于算法设计的问题
本程序设计了一个学期,在调试修改过程中很多算法结构都做了多次修改,尽量对可能出现的错误进行预防处理。这方面的调试修改很多,大致罗列一二:
比如程序中所有要求输入的地方,都根据具体情况先对输入字符进行输入判断,防止因输入错误导致程序出错。
又如在处理员工编号的问题时,原先设计在新增信息时员工编号为员工总数加1000,以达到由1001开始增序排列。但是后来在测试删除函数时发现,当删除员工不是最后一个时,再新增员工信息,则会产生编号相同的信息。于是考虑修改编号设置方法为:如文件保存无员工信息,则新增信息为第一个,编号设为1001,否则新增员工编号设为最后一个员工的编号加一,以达到编号递增排列的设计目的。
5.2心得体会
      “简单的职工管理系统”设计是本学期数据结构课程唯一的课程设计。在设计这个程序的过程中,我遇到过许多问题,也学到了很多东西。本程序的设计实现主要是用C++语言实现,通过对程序算法的设计优化、输出显示的格式设计、输入过程中的异常处理等一些设计过程中的问题的考虑解决,在C++学习上也有了很大的进步。程序设计过程中开始遇到的最大的问题是算法的结构设计问题,实验指导上只给了简单设计的要求,要真正实现还需要考虑很多方面。在算法的数据结构设计上考虑了很长时间。在程序设计中先后参考了很多网络资料,也参考了一些别人写的的程序,综合这些算法思想和自己的思路对程序做了很好的设计方式,对一些算法的优越性等也作了一些考虑。此外考虑最多的就是异常错误处理的设计。一个好的程序必须能在各种环境下都有其相应的处理方式,至少能应对一些常见的可能发生的错误。比如一般的要求输入为数字时,如果输入了一个非数字字符,程序就会立即出错无法继续运行,本程序针对这个问题设计了一个shuzi();函数进行处理,处理方式为:接受键盘输入的字符为字符串,然后对字符串的每个字符进行判断是否为数字,如果有非数字字符出现则提示出错并要求重新输入。又如在判断是否继续时要求输入Y/N时,按一般的方式,如果输入为多个字符,则多余的字符会保存在缓冲区,到下次要求输入时输入而导致出错,对此问题设计处理方式为接受输入字符保存为串然后只取其首字符进行判断。还有很多类似的错误处理。还有在设置程序的显示优化时,发现暂停函数在不同的情况下执行顺序不同,如此等等。在课程设计过程中遇到了许多问题,也向同宿舍的同学做了一些请教一起讨论,也因此从他们身上学到了许多东西。
6. 参考文献 (包括书籍、论文、网络资料等)
[1] 刘璟等.《高级语言c++程序设计》.北京:高等教育出版社,2006.03.
 [2] 严蔚敏等.《数据结构(C语言版)》.北京:清华大学出版社,2007.4
相关工具:
Microsoft Visual C++ 6.0
Bloodshed Dev-C++
附录 程序源代码
/*
[设计题目]简单的职工管理系统
[问题描述]
    对单位的职工进行管理,包括插入、删除、查找、排序等功能。
[基本要求]
    职工对象包括姓名、性别、出生年月、工作年月 的方法。在此基础上实现增、删、查询、修改等操作。
  */
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
const N=50; //定义系统可录入的员工最大数值
string Ename[N];  //姓名
long Enum[N];     //人数
char Esex[N];     //性别
int Eage[N];      //年龄
string Eborndate[N];  //出生年月
string Eworkdate[N];  //工作年月
int Edegree[N];  //学历
int Eposition[N]; //职位
string Eaddress[N]; //住址
string Ephone[N];   //电话
int shuzi(int sz); //数字判断函数  也可使用 void shuzi(int& sz); 方式
//员工管理类
class Employee{
public:
    string Employeename; //姓名
    long Employeenum; //人数
    char Employeesex; //性别
    int Employeeage;  //年龄
    string Employeeborndate;  //出生年月
    string Employeeworkdate;  //工作年月
    int Employeedegree;     //学历
 int Employeeposition;   //职位
    string Employeeaddress; //住址
    string Employeephone;   //电话
 static long EmployeeMaxNum;
    void NewInfo(); //添加新成员函数
    void ShowInfo(); //员工信息查询函数
    void showall();  //全体员工输出函数
    void showdegree(int degree); //按学历输出函数
    void showage(int min,int max); //按年龄段输出函数
    void shownum(long number); //按编号输出函数
    void RefreshInfo();  //修改员工信息函数 
    void DeleteInfonum(int cNum);//按编号删除员工数据函数
 void DeleteInfodegree(int degree);//按学历删除员工数据函数
 void DeleteInfoname(string name);//按姓名删除员工数据函数
    void DeleteInfoall(); //删除所有员工信息函数
    void DeleteInfo(); //删除员工信息函数
    static int MaxNum();//返回系统已存储人数函数
};
//文件操作类
class DBOperate{
public:
    string Employeename;
    long Employeenum;
    char Employeesex;
    int Employeeage;
    string Employeeborndate;
    string Employeeworkdate;
    int Employeedegree;
 int Employeeposition;
    string Employeeaddress;
    string Employeephone;
    static long EmployeeMaxNum;
    void WriteIn(int iflag); //数据写入操作函数
    void ReadOut(); //数据读出操作函数
    void RefreshMaxNum(int iflag); //更新系统中员工计数文件函数
};
//==============类Employee 成员函数定义================
long Employee::EmployeeMaxNum = 1000;//员工编号基数从10001开始
//===返回系统已存储人数函数===
int Employee::MaxNum(){
    int mn=0;
    ifstream EMN;
    EMN.open("EmployeeMaxNum.txt");
    EMN>>mn;
  //  cout<<mn<<endl;
    EMN.close();
    return mn;
}
//===添加新成员函数===
void Employee::NewInfo(){
 DBOperate dbo;
 dbo.ReadOut(); //读取存储文件
    cout<<"新员工姓名: ";
    cin>>Employee::Employeename;
 if(Employee::MaxNum()==0)
  Employee::Employeenum = EmployeeMaxNum + Employee::MaxNum()+1; //员工编号依次递增
 else Employee::Employeenum = dbo.Employeenum+1;  //编号为最后一个员工编号加一递增
 do{
  cout<<"新员工性别: [F为女性,M为男性]: ";
  char*tmp00=new char;
  cin>>tmp00;//输入存为字符串,然后取其首首字符进行判断,处理输入多个字符出错问题
  Employee::Employeesex=*tmp00;
  if(Employee::Employeesex !='f' && Employee::Employeesex !='F'&& Employee::Employeesex !='m'&& Employee::Employeesex !='M')
   cout<<"输入错误,请重新输入!"<<endl;
 }while(Employee::Employeesex !='f' && Employee::Employeesex !='F'&& Employee::Employeesex !='m'&& Employee::Employeesex !='M');
    cout<<"新员工年龄: ";
    Employee::Employeeage=shuzi(Employee::Employeeage);
    cout<<"新员工出生年月: ";
    cin>>Employee::Employeeborndate;
 cout<<"新员工工作年月: ";
    cin>>Employee::Employeeworkdate;
    cout<<"新员工学历,请输入相应学历的序号: "<<endl;
    cout<<" [1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士] ";
    Employee::Employeedegree=shuzi(Employee::Employeedegree);
    while(Employee::Employeedegree !=1&&Employee::Employeedegree !=2&&Employee::Employeedegree !=3&&Employee::Employeedegree !=4&&Employee::Employeedegree !=5&&Employee::Employeedegree !=6&&Employee::Employeedegree !=7&&Employee::Employeedegree !=8){
  cout<<"输入有误,请重新输入:"<<endl;
  cout<<" [[1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士]";
        Employee::Employeedegree=shuzi(Employee::Employeedegree);
 }
 cout<<"新员工职位, 请输入相应职位的序号: "<<endl;
 cout<<" [1:临时职员 2: 正式职员 3:主任 4:部门经理 5:总经理 6:董事长] ";
 Employee::Employeeposition=shuzi(Employee::Employeeposition);
 while(Employee::Employeeposition !=1&&Employee::Employeeposition !=2&&Employee::Employeeposition !=3&&Employee::Employeeposition !=4&&Employee::Employeeposition !=5&&Employee::Employeeposition !=6){
  cout<<"输入有误,请重新输入:"<<endl;
  cout<<" [1:临时职员 2: 正式职员 3:主任 4:部门经理 5:总经理 6:董事长] ";
  Employee::Employeeposition=shuzi(Employee::Employeeposition);
 }
  cout<<"新员工住址: ";
    cin>>Employee::Employeeaddress;
 cout<<"新员工电话: ";
    cin>>Employee::Employeephone;
// DBOperate dbo;
// dbo.ReadOut(); //读取存储文件
 int MaxNum = Employee::MaxNum(); //员工总人数
 Enum[MaxNum] = Employee::Employeenum;
 Ename[MaxNum] = Employee::Employeename;
 Esex[MaxNum] = Employee::Employeesex;
 Eage[MaxNum] = Employee::Employeeage;
 Eborndate[MaxNum] = Employee::Employeeborndate;
 Eworkdate[MaxNum] = Employee::Employeeworkdate;
 Edegree[MaxNum] = Employee::Employeedegree;
 Eposition[MaxNum] = Employee::Employeeposition;
 Eaddress[MaxNum] = Employee::Employeeaddress;
 Ephone[MaxNum] = Employee::Employeephone;
 dbo.WriteIn(1); //新增员工信息写入文件
 cout<<"nttt添加新成员成功!"<<endl;
 cout<<"==========================================="<<endl;
}
//===员工信息查询函数===
void Employee::ShowInfo(){
    char *choice1=new char;
 int choice2,min,max;
 long searchnum;
 Employee e;
 cout<<" 请选择查询方式:"<<endl;
 cout<<"t==========================================="<<endl;
 cout<<"t*  输出全体职工信息——————— 1"<<endl;
 cout<<"t*  按职工学历输出———————– 2"<<endl;
 cout<<"t*  按职工年龄段输出——————— 3"<<endl;
 cout<<"t*  按职工编号输出———————– 4"<<endl;
 cout<<"t*  返回——————————— 5"<<endl;
 cout<<"t==========================================="<<endl;
 do{
  cout<<" 请选择:";
  cin>>choice1;
  cout<<"===========================================n";
  switch(*choice1) {
  case '1':
   showall();break;
     case '2':
   do{
    cout<<"请输入要查询职工的学历编号: n[1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士]: ";
    choice2=shuzi(choice2); //调用数字判断函数进行出错预防处理
    if(choice2<1||choice2>8)
     cout<<"输入的数据不在1—8内! 请重新输入!"<<endl;
    cout<<endl;
   }while(choice2<1||choice2>8);
   e.showdegree(choice2);break;
     case '3':
      cout<<"请输入要查询的年龄范围: "<<endl;
      cout<<"t最小值: ";
      min=shuzi(min);
      cout<<"t最大值: ";
      max=shuzi(max);
      e.showage(min,max);break;
     case '4':
      cout<<"请输入要查询的员工号: ";
      cin>>searchnum;
      e.shownum(searchnum);break;
     case '5':  break;
     default:
      cout<<"输入错误!请检查后重新输入! "<<endl;break;
  }
 }while(*choice1<'1'||*choice1>'5');
}
//===全体员工输出函数===
void Employee::showall(){ //输出一个数据信息暂停一下
 int i;
 long number;
 for(i=0;i<Employee::MaxNum();i++){
  number = Enum;
  shownum(number); //调用按员工编号输出函数
 }
}
//===按员工学历输出函数===
void Employee::showdegree(int degree){
 int i;
 switch(degree){
 case 1:cout<<"小学学历的员工有:"<<endl;break;
 case 2:cout<<"初中学历的员工有:"<<endl;break;
 case 3:cout<<"中专学历的员工有:"<<endl;break;
 case 4:cout<<"高中学历的员工有:"<<endl;break;
 case 5:cout<<"专科学历的员工有:"<<endl;break;
 case 6:cout<<"本科学历的员工有:"<<endl;break;
 case 7:cout<<"硕士学位的员工有:"<<endl;break;
 case 8:cout<<"博士学位的员工有:"<<endl;break;
 }
 bool temp=false;
 for(i=0;i<Employee::MaxNum();i++){
  if(Edegree == degree){
   long number = Enum;
   shownum(number); //调用按员工编号输出函数
   temp=true;//找到相关数据则temp 置为真
  }
  else continue;
 }
 if(temp==false){
  cout<<"nttt未找到相关数据!"<<endl;
  cout<<endl;system("pause");//暂停一下,放在IF判断内
 }
}
//===按员工年龄段输出函数===
void Employee::showage(int min,int max){
 int i;
 bool temp=false;
 for(i=0;i<Employee::MaxNum();i++){
  if(Eage>=min&&Eage<=max){
   long number = Enum;
   shownum(number);//调用按员工编号输出函数
   temp=true;
  }
  else continue;
 }
 if(temp==false){
  cout<<"nttt未找到相关信息!"<<endl;
  cout<<endl;system("pause");
 }
}
//===按员工编号输出函数===
void Employee::shownum(long number){
 int i;
 bool temp1=false;
 for(i=0;i<Employee::MaxNum();i++){
  if(Enum == number){
   cout<<"=================================="<<endl;
   cout<<" 员工编号 > "<<Enum<<endl;
   cout<<" 姓    名 > "<<Ename<<endl;
   cout<<" 性    别 > ";
   if(Esex=='f'||Esex=='F') cout<<"女 "<<endl;
   else
    if(Esex=='m'||Esex=='M') cout<<"男 "<<endl;
   cout<<" 年    龄 > "<<Eage<<"岁"<<endl;
   cout<<" 出生年月 > "<<Eborndate<<endl;
   cout<<" 学    历 > ";
   switch (Edegree){
   case 1:
    cout<<"小 学 "<<endl;break;
   case 2:
    cout<<"初 中 "<<endl;break;
   case 3:
    cout<<"中 专 "<<endl;break;
   case 4:
    cout<<"高 中 "<<endl;break;
   case 5:
    cout<<"专 科 "<<endl;break;
   case 6:
    cout<<"本 科 "<<endl;break;
   case 7:
    cout<<"硕 士 "<<endl;break;
   case 8:
    cout<<"博 士 "<<endl;break;
   }    
   cout<<" 所任职务 > ";
   switch (Eposition){
   case 1:
    cout<<"临时成员 "<<endl;break;
   case 2:
    cout<<"正式员工 "<<endl;break;
   case 3:
    cout<<"主任 "<<endl;break;
   case 4:
    cout<<"部门经理 "<<endl;break; 
   case 5:
    cout<<"总经理 "<<endl;break;
   case 6:
    cout<<"董事长 "<<endl;break;
   }
   cout<<" 住    址 > "<<Eaddress<<endl;
   cout<<" 电    话 > "<<Ephone<<endl;
   cout<<"=================================="<<endl;
      temp1=true;//找到记录temp置为真
  }
 }
 cout<<endl;
 if(temp1==false)cout<<"nttt未找到相关信息!"<<endl;
 system("pause");//cout<<endl;
}
//===修改员工信息函数===
void Employee::RefreshInfo(){
 int cNum = 1000;
 DBOperate dbo;
 dbo.ReadOut(); //读入文件保存的内容
 cout<<"请输入您要修改的员工编号: > ";
 cNum=shuzi(cNum);//调用数字判断函数
 int MN;
 MN = Employee::MaxNum();
 char*temp1=new char;
 bool temp=false;
 for(int i=0;i<MN;i++){ //遍历数据文件,查找要修改的员工数据
  if(Enum == cNum){
   temp=true;//找到相关信息则temp 置为真
   Employee::shownum(cNum);
            cout<<"n 是否真的要修改该信息?(y/n):";
   cin>>temp1;
   if(*temp1=='y'||*temp1=='Y'){
    cout<<"请输入该员工的新信息: "<<endl;
    cout<<"新员工姓名: "; //录入员工的新的数据,员工号保持不变
    cin>>Employee::Employeename;
    Ename = Employee::Employeename;
    do{
     cout<<"新员工性别: [F为女性,M为男性]: ";
     cin>>Employee::Employeesex;
     if(Employee::Employeesex !='f' && Employee::Employeesex !='F'&& Employee::Employeesex !='m'&& Employee::Employeesex !='M')
      cout<<"输入错误,请重新输入!"<<endl;
    }while(Employee::Employeesex !='f' && Employee::Employeesex !='F'&& Employee::Employeesex !='m'&& Employee::Employeesex !='M');
    Esex = Employee::Employeesex;
    cout<<"新员工年龄: ";
    cin>>Employee::Employeeage;
    Eage = Employee::Employeeage;
    cout<<"新员工出生年月: ";
    cin>>Employee::Employeeborndate;
    Eborndate = Employee::Employeeborndate;   
    cout<<"新员工工作年月: ";
    cin>>Employee::Employeeworkdate;
    Eborndate = Employee::Employeeworkdate;
    cout<<"新员工学历,请输入相应学历的序号:"<<endl;
    cout<<" [[1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士] ";
    Employee::Employeedegree=shuzi(Employee::Employeedegree);
    while(Employee::Employeedegree !=1&&Employee::Employeedegree !=2&&Employee::Employeedegree !=3&&Employee::Employeedegree !=4&&Employee::Employeedegree !=5&&Employee::Employeedegree !=6&&Employee::Employeedegree !=7&&Employee::Employeedegree !=8){
     cout<<"输入有误,请重新输入:"<<endl;
     cout<<" [[1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士] ";
     Employee::Employeedegree=shuzi(Employee::Employeedegree);
    }
    Edegree = Employee::Employeedegree;
    cout<<"新员工职位,请输入相应职位的序号:"<<endl;
    cout<<" [1:临时职员 2: 正式职员 3:主任 4:部门经理 5:总经理 6:董事长] ";
    Employee::Employeeposition=shuzi(Employee::Employeeposition);
    while(Employee::Employeeposition !=1&&Employee::Employeeposition !=2&&Employee::Employeeposition !=3&&Employee::Employeeposition !=4&&Employee::Employeeposition !=5&&Employee::Employeeposition !=6){
     cout<<"输入有误,请重新输入:"<<endl;
     cout<<" [1:临时职员 2: 正式职员 3:主任 4:部门经理 5:总经理 6:董事长] ";
     Employee::Employeeposition=shuzi(Employee::Employeeposition);
    }
    Eposition = Employee::Employeeposition;
    cout<<"新员工的地址 : ";
    cin>>Employee::Employeeaddress;
    Eaddress = Employee::Employeeaddress;
    cout<<"新员工的电话 : ";
    cin>>Employee::Employeephone;
    Ephone = Employee::Employeephone;
   }
   else{ temp=false; *temp1='n';}//用于后面的提示输出判断
   break;
  }
 }
 if(temp==false){
  if(*temp1=='n');
  else
   cout<<"nttt未找到输入的编号员工的信息!"<<endl;
 }
 else{
  dbo.WriteIn(0);  //写入修改后的信息到文件
  cout<<"ttt修改成功!"<<endl;
 }
 cout<<"=================================="<<endl;
 cout<<endl;system("pause");
}
//===按编号删除员工数据函数===
void Employee::DeleteInfonum(int cNum){
 char* tmp=new char;
 bool temp=false;
 DBOperate dbo;
 dbo.ReadOut();//读出文件内容到内存
 int MN;
 MN = Employee::MaxNum();
 for(int i=0;i<MN;i++)//遍历数据文件,查找要删除的员工
  if(Enum == cNum){
   temp=true;//找到相关信息则置为真
   Employee::shownum(cNum);
   break;
  }
 if(temp==false)
  cout<<"nttt未找到输入编号的相关数据!"<<endl;
 else{
  cout<<"确认要删除该员工信息?(Y为确认 N为放弃): ";
  cin>>tmp;
  if(*tmp=='Y'||*tmp=='y'){
   if(i==MN-1)
    dbo.WriteIn(-1);
   else{
    for(int j=i;j<MN-1;j++) Enum[j] = Enum[j+1];
    dbo.WriteIn(-1);
   }
   cout<<"nttt删除操作成功 ! "<<endl;
  }
 }
 cout<<"tt======================================"<<endl;
 cout<<endl;system("pause");
}
//===按学历删除员工数据函数===
void Employee::DeleteInfodegree(int degree){
 int i;
 DBOperate dbo;
 dbo.ReadOut();//读出文件内容到内存
 char *tmp=new char;
 int MN;
 MN = Employee::MaxNum();
 switch(degree){
 case 1:
  Employee::showdegree(1);
  cout<<"确认删除小学学历的员工数据?(Y为确认 N为放弃): ";break;
 case 2:
  Employee::showdegree(2);
  cout<<"确认删除初中学历的员工数据?(Y为确认 N为放弃): ";break;
 case 3:
  Employee::showdegree(3);
  cout<<"确认删除中专学历的员工数据?(Y为确认 N为放弃): ";break;
 case 4: 
  Employee::showdegree(4);
  cout<<"确认删除高中学历的员工数据?(Y为确认 N为放弃): ";break;
 case 5: 
  Employee::showdegree(5);
  cout<<"确认删除专科学历的员工数据?(Y为确认 N为放弃): ";break;
 case 6:
  Employee::showdegree(6);
  cout<<"确认删除本科学历的员工数据?(Y为确认 N为放弃): ";break;
 case 7:
  Employee::showdegree(7);
  cout<<"确认删除硕士学位的员工数据?(Y为确认 N为放弃): ";break;
 case 8:
  Employee::showdegree(8);
  cout<<"确认删除博士学位的员工数据?(Y为确认 N为放弃): ";break;
 }
 cin>>tmp;
 if(*tmp=='Y'||*tmp=='y'){
  for(i=0;i<MN;i++){
   if(Edegree == degree){
    long number = Enum;
    if(i==MN-1)
     dbo.WriteIn(-1);
    else{
     for(int j=i;j<MN-1;j++) Enum[j] = Enum[j+1];
     dbo.WriteIn(-1);
    }
   }
   else continue;
  }
  cout<<"nttt删除操作成功 ! "<<endl;
 }
 cout<<"tt======================================"<<endl;
 cout<<endl;system("pause");
}
//===按姓名删除员工数据函数===
void Employee::DeleteInfoname(string name){
 int i;
 bool temp=false;
 char *tmp=new char;
 int MN;
 MN = Employee::MaxNum();
 DBOperate dbo;
 dbo.ReadOut();//读出文件内容到内存
 for(i=0;i<MN;i++){//遍历数据文件,查找要删除的员工
  if(Ename == name){
   temp=true;//找到相关信息则置为真
   Employee::shownum(Enum);// 删除前先显示该姓名的信息
   cout<<"确认删除(Y/N)?:";
   cin>>tmp;
   if(*tmp=='Y'||*tmp=='y'){
    for(int i0=0;i0<MN;i0++){
     if(Ename[i0] == name){
      long number = Enum;
      if(i0==MN-1)
       dbo.WriteIn(-1);
      else{
       for(int j=i0;j<MN-1;j++) Enum[j] = Enum[j+1];
       dbo.WriteIn(-1);
      }
      cout<<"nttt  删除操作成功 ! "<<endl;
      break;//删除该姓名信息后跳出,进入下轮寻找
     }
    }
   }
   else{
    cout<<"是否继续查找?(Y/N):";cin>>tmp;
    if(*tmp!='Y' && *tmp!='y') break;
   }
  }
 }//for
 if(temp==false)
  cout<<"nttt未找到输入姓名的相关数据!"<<endl;
// else
//  cout<<"nttt  删除操作成功 ! "<<endl;
 
 cout<<"tt======================================"<<endl;
 cout<<endl;system("pause");
}
//===删除所有员工数据函数===
void Employee::DeleteInfoall(){
 int i;
 DBOperate dbo;
 dbo.ReadOut(); //读出文件内容到内存
 char *tmp=new char;
 int MN;
 MN = Employee::MaxNum();
 cout<<"确认删除(Y/N)?:";
 cin>>tmp;
 if(*tmp=='Y'||*tmp=='y'){
  for(i=MN-1;i>=0;i–){
 //  long number = Enum;
 //  if(i==MN-1)
    dbo.WriteIn(-1);
 //  else{
 //   for(int j=i;j<number-1;j++) Enum[j] = Enum[j+1];
 //   dbo.WriteIn(-1);
 //  }
  }
  cout<<"nttt删除操作成功 ! "<<endl;
 }
 cout<<"tt======================================"<<endl;
 cout<<endl;system("pause");
}
//===删除员工数据函数===
void Employee::DeleteInfo(){
 char* tmp=new char;
 bool temp=false;
 char* choice=new char;
 int choice2;
 string TEname;
 int cNum;
 do{
  cout<<" 请选择删除方式:"<<endl;
  cout<<"t==========================================="<<endl;
  cout<<"t*  按编号删除—————————- 1"<<endl;
  cout<<"t*  按职工学历删除———————— 2"<<endl;
  cout<<"t*  按职工姓名删除———————— 3"<<endl;
  cout<<"t*  删除全部—————————— 4"<<endl;
  cout<<"t*  返回———————————- 5"<<endl;
  cout<<"t==========================================="<<endl;
  cout<<"请选择:";
  cin>>choice;
  cout<<endl;
  cout<<"======================================"<<endl;  
  switch(*choice){
  case '1':
   cout<<"请输入要删除员工的编号:";
   cNum=shuzi(cNum);//调用数字判断函数
   Employee::DeleteInfonum(cNum);
   break;
     case '2':
   do{
    cout<<"请输入要查询职工的学历编号: n[1:小学 2:初中 3:中专 4:高中 5:专科 6:本科 7:硕士 8:博士]: ";
    choice2=shuzi(choice2); //调用数字判断函数进行出错预防处理
    if(choice2<1||choice2>8)
     cout<<"输入的数据不在1—8内! 请重新输入!"<<endl;
     cout<<endl;
   }while(choice2<1||choice2>8);
   Employee::DeleteInfodegree(choice2);
   break;
  case '3':
   cout<<"请输入要删除的员工的姓名:";
   cin>>TEname;
   Employee::DeleteInfoname(TEname);
   break;
   case '4':
   Employee::DeleteInfoall();
   break;
  case '5': break;
     default:
      cout<<"输入错误!请检查后重新输入! "<<endl;break;
  }
 }while(*choice<'1'||*choice>'5');
}
//====================类DBOperate 成员函数定义=======================
//===数据写入操作函数===
void DBOperate::WriteIn(int iflag){
 DBOperate::RefreshMaxNum(iflag);
 ofstream myf("Employee.txt");
 Employee e;
 int MN;
 MN = e.MaxNum();
 for(int i=0;i<MN;i++){//按顺序将依次保存全局变量内容到文件
  myf<<Enum<<'n'<<Ename<<'n'<<Esex<<'n'<<Eage<<'n'<<Eborndate<<'n'<<Eworkdate<<'n'<<Edegree<<'n'<<Eposition<<'n'<<Eaddress<<'n'<<Ephone<<'n';
 }
 myf.close();
 return;
}
//===读出数据操作函数===
void DBOperate::ReadOut(){
 ifstream myf("Employee.txt");
 Employee e;
 int MN;
 MN = e.MaxNum();
 for(int i=0 ;i<MN;i++){//按顺序将文件内容依次读出并保存到全局变量中
  myf>>DBOperate::Employeenum>>DBOperate::Employeename>>DBOperate::Employeesex>>DBOperate::Employeeage>>DBOperate::Employeeborndate>>DBOperate::Employeeworkdate>>DBOperate::Employeedegree>>DBOperate::Employeeposition>>DBOperate::Employeeaddress>>DBOperate::Employeephone;
  Enum = DBOperate::Employeenum;
  Ename = DBOperate::Employeename;
  Esex = DBOperate::Employeesex;
  Eage = DBOperate::Employeeage;
  Eborndate = DBOperate::Employeeborndate;
  Eworkdate = DBOperate::Employeeworkdate;
  Edegree = DBOperate::Employeedegree;
  Eposition = DBOperate::Employeeposition;
  Eaddress = DBOperate::Employeeaddress;
  Ephone = DBOperate::Employeephone;
 }
 myf.close();
}
//===更新系统中员工计数文件的函数 ===
void DBOperate::RefreshMaxNum(int iflag){
 int MaxNum = 0;
 ifstream myif("EmployeeMaxNum.txt");
 myif>>MaxNum;//读出文件保存内容到内存
 myif.close();
 MaxNum = MaxNum+iflag;
 ofstream myof("EmployeeMaxNum.txt");
 myof<<MaxNum;//内存中更新后的数据写入到文件
 myof.close();
}
//===数字判断函数===
int shuzi(int sz){//输入数据并判断是否为数字
    char *temp;
    temp=new char; //临时指针,存放输入字符
    int len; //存储取字符的长度
    sz=0 ; //清零
    char s;
    do{
  cin>>temp;
        len=strlen(temp); //取字符长度
        for(int i=0;i<len;i++){
           s= *(temp+i);
           if(s<'0' || s>'9'){
               cout<<" 笨蛋,输错了! 你输入的是数字吗?! nn";
      cout<<"请重新输入:";
      break;
           }
        }
    }while(s<'0' || s>'9');  
    for(int i=0;i<len;i++){//输入字符串转化为整形数字  
        int t=1;
        for(int j=1;j<len-i;j++) t*=10;
        sz+=(*(temp+i)-48)*t;  
    }
 return sz;
}
//===签名函数 ===
void sign(){
   system("cls");//清屏
   cout<<endl<<endl<<endl<<endl<<endl<<endl;
   cout<<"tt ========================================="<<endl;
   cout<<"tt =@                                     @="<<endl;
   cout<<"tt =@          本程序由李志文制作         @="<<endl;
   cout<<"tt =@             谢谢你的使用            @="<<endl;
   cout<<"tt =@          版权没有,随便复制         @="<<endl;
   cout<<"tt =@                                     @="<<endl;
   cout<<"tt =@            洛阳师院 08.5            @="<<endl;
   cout<<"tt =@                                     @="<<endl;
   cout<<"tt ========================================="<<endl;
   cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
    system("pause");//暂停  比较两种方式   getch();
/*     经过在不同的编辑器中调试发现,不同的调试器对函数执行的顺序有差别
    如在此处使用 getch() 和 system("pause") 函数时,在visual c++6.0中先执行此函数再显示,
    而在dev-c++ 中则按顺序执行
    对此问题我在很多地方搜索查找均未找到满意的答案,本次换用调试器才发现理解–4.29
       本次调试格式时,将换行命令 "n" 改为 endl 时,发现 system("pause") 函数执行变为顺序
    执行
查找了一下相关帮助:
      在OSTREAM.H中有这样的一个inline函数:
      inline _CRTIMP ostream& __cdecl endl(ostream& _outs) { return _outs << 'n' << flush; }
      也就是说
      endl= return _outs << 'n' << flush;
      endl除了写'n'进外,还调用flush函数,刷新缓冲区,把缓冲区里的数据写入文件或屏幕,
      如果考虑效率就用'n'    –5.14
 */
   cout<<"ttt";
}
//===主函数===
int main(){
 system("color 06f"); //设置当前窗口的背景色和前景色
 char* select;
 select=new char;
 while(*select!='5'){
  do{
   cout<<"t===========================主菜单==========================="<<endl;
            cout<<"t     请选择功能"<<endl;
            cout<<"t————————————————————"<<endl;
            cout<<"t         1.新建并输入职工数据"<<endl;
            cout<<"t         2.按条件输出职工数据"<<endl;
            cout<<"t         3.修改指定职工的数据"<<endl;
            cout<<"t         4.删除数据"<<endl;
            cout<<"t         5.退出"<<endl;
      cout<<"t============================================================"<<endl;
      cout<<"t————————————————————"<<endl;
      cout<<" 请选择您要服务的类别: " ;
      cin>>select;
   cout<<"n===========================================n";
      Employee e;
      DBOperate dbo;
      switch(*select){
      case '1': e.NewInfo(); break;
      case '2':
    dbo.ReadOut();
    e.ShowInfo(); break;
   case '3': e.RefreshInfo(); break;
   case '4': e.DeleteInfo(); break;
   case '5': sign();break;
   default:
    cout<<"输入错误,请重新输入!"<<endl;
   }
   cout<<endl<<endl;
  }while(*select<'1'||*select>'5');
    }
 exit(1);
 return 0;
}
点赞 (0)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code