欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++抽象编程——简单的员工信息管理系统

程序员文章站 2022-04-10 23:40:03
...

本来打算今天要写的是快速排序的,那只能等明天了。因为今天突然有个老同学叫我帮她写一个简单的员工管理系统。我从下午3点写到6点30分(没办法,毕竟我也才大二)。最后大致写了个大概,我就把他们的题目拿出来一下吧
C++抽象编程——简单的员工信息管理系统
实际上我们学校是没有具体讲文件处理的。但是我之前谢写过我们可以用map来处理。所以我就大胆的尝试了一下,没想到就真的可以。下面我把代码奉上:

头文件

/*
 *这个文件定义了一个抽象类,里面包含了对系统的一系列操作
 */
#ifndef _MannagmentSystem_h
#define _MannagmentSystem_h
/*
 *声明类
 */ 
class ManagmentSystem;
class ManagmentStaff;
/*
 *定义 ManagmentSystem,里面的功能包括了,删除信息,添加信息
 *显示文件信息,查找文件信息的功能,还有用于程序运行接口的菜单。
 *输出程序介绍。最后的是退出程序。
 */ 
class ManagmentSystem{
    public: 
    /*
     *下面两个方法我声明为纯虚函数,原因是因为我在管理系统里不能
     *删除或者添加东西,要读取文件以后才可以。但是后面的成员类可以
     *用到,所以定义为纯虚函数
     */ 
        virtual void deleteInformation(){};
        virtual void addInformation(){};
        /*
         *下面的方法,并没有定义为虚函数。原因是
         *它们不涉及到文件的修改,只是查找,和显示内容
         */ 
        void displayInformation();
        void searchInformation();
        void welcomeInformation();
        void menu();
        void quitSystem();
}; 
/*这个类继承于 ManagmentSystem*/ 
class ManagmentStaff:public ManagmentSystem{
    public:
        void deleteInformation();
        void addInformation();
        void changeInformation();   
};

#endif

我实在不明白为什么一定要用虚函数,如果不用,我肯定能写的更加简短。

实现文件

/*
 *这个文件实现Managment接口的所有函数
 */
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <map>
#include <cctype>
#include "Managment.h"
using namespace std;
/*函数原型*/ 
bool isRightCommand(char ch);
bool isFind(map<string,string> mymap, string code);
void readCodeFile(map<string,string> & mymap);
void backToMenu(); 

/*
 *方法: welcomeInformation
 *用法:ms.welcomeInformation();
 *------------------------------
 *这个方法输出主要的系统信息,输入m进入菜单选项
 *<cctype>中的toupper函数将输入的字母转换成大写,
 *这样可以忽略用户的大小写输入,用户友好度提高
 */ 
void ManagmentSystem::welcomeInformation(){
    cout << "********************************" << endl;
    cout << "*     欢迎使用员工管理系统     *" << endl;
    cout << "*此系统可以管理的信息,信息包括*" << endl;
    cout << "*工号,姓名,年龄,工资。这个系*" << endl;
    cout << "*统包含6个功能,输入m或M,进入菜*" << endl;
    cout << "*单.所有产生的文件存在F盘my.txt*" << endl;
    cout << "********************************" << endl;
    char ch;
    cin >> ch;
    if(toupper(ch) == 'M'){
        ManagmentSystem mst;
        ManagmentSystem *ms = &mst;
        ms -> menu(); 
    } 
}
/*
 *方法: menu();
 *用法:ms.menu();
 *-----------------
 *系统的管理菜单,用接收一系列的操作指令
 *这里同样用的是toupper函数,然后我们写一个isRightCommand判断
 *用户输入的指令是否在指定的范围内
 *然后我们根据不同的指令,创建不同的对象,然后用 -> 运算符指向
 *所要的功能 
 */ 
void ManagmentSystem::menu(){
    cout << "********************************" << endl;
    cout << "*请输入你要进行的操作指令:    *" << endl;
    cout << "*  d或D:显示当前的职工信息    *" << endl;
    cout << "*  s或S:查找员工信息          *" << endl;
    cout << "*  c或C:修改某个员工的信息    *" << endl;
    cout << "*  e或E:删除某个员工的信息    *" << endl;
    cout << "*  a或A:增加员工信息          *" << endl;
    cout << "*  q或Q:退出系统              *" << endl;
    cout << "********************************" << endl; 
    char ch; 
    cin >> ch;
    ch = toupper(ch); 
    ManagmentSystem mst;ManagmentStaff msff;
    ManagmentSystem *ms = &mst;
    ManagmentStaff *msf = &msff;
    if(isRightCommand(ch)){
    switch(ch){
        case 'D':
            ms -> displayInformation();
            break;
            case 'S':
                ms -> searchInformation();
                break;
                case 'E':
                    msf -> deleteInformation();
                    break;
                    case 'A':
                        msf -> addInformation();
                        break;
                        case 'Q':
                            ms -> quitSystem();
                            case 'C':
                            msf -> changeInformation();
                            break;      
        }
    }else{
        cout << "你输入的指令有误" << endl; 
        ms -> menu();
    }
}


/*
 *方法: displayInformation
 *用法: displayInformation()
 *------------------------------ 
 *这个方法用于查看当前的文件信息
 *其实质的功能就是打开一个文件,将文件的信息输入到流中
 */ 
void ManagmentSystem::displayInformation(){
    ifstream infile;
    infile.open("F:\\my.txt");
    if (infile.fail()){
        infile.clear();
        cout << "打开文件失败" << endl;
    }else{
        cout << "文件名:my.txt" << endl;
    }
    //根据单个字符逐个读取 
    while (true) {
      int ch = infile.get();//用get方法获取字符 
      if (ch == EOF) break; //EOF是结束符 
      cout.put(ch);
    }
    infile.close();  //关闭文件
    backToMenu();//返回菜单 
}
/*
 *方法:addInformation
 *用法:msff.addInformation()
 *---------------------------
 *在文本的末尾添加员工信息
 *ios::app,在打开文件后自动指向文末尾。 
 *这里,员工添加的信息有4个:工号,姓名,年龄,工资
 *outfile << 将数据写入到文件中,类似于cout。
 *输入完毕,输出个回车,这样数据就一组数据一行,好看又便于管理
 *其实文件的保存,就是写入完毕后用close方法关闭。 
 */ 
void ManagmentStaff::addInformation(){
    ManagmentSystem mst;
    ManagmentSystem *ms = &mst;
    ofstream outfile;
    outfile.open("F:\\my.txt",ios::out|ios::app); 
    if (outfile.fail()){
        outfile.clear();
        cout << "打开文件失败" << endl;
    }
    cout << "请输入你要添加的员工信息(输入1开始添加,输入0结束添加):" 
    << endl;
    while(true){
        int i;
        cin >> i;
        if(i == 0) {
            ms -> menu();
            break;
        } 
        if(i == 2){
            cout << "保存成功" << endl; 
            outfile.close();
            ms -> menu();
            break;
        }
        cout << "请输入员工的工号(4位数):" << endl;
        int n; cin >> n;
        outfile << n << "=";
        cout << endl;
        cout << "请输入员工的姓名:" << endl;
        string str; cin >> str;
        outfile << str << ",";
        cout << endl;
        cout << "请输入员工的年龄:" << endl;
        int a; cin >> a;
        outfile << a << ",";
        cout << endl;
        cout << "请输入员工的工资:" << endl;
        int w; cin >> w;
        outfile << w << ",";
        outfile << "\n"; //文件换行处理 
        cout << endl; 
        outfile.seekp(0,ios::end);
        cout << "成功创建员工信息!";
        cout << "请继续输入指令,1继续输入,0返回菜单,2保存数据" << endl;
  }
}
/*
 *方法: searchInformation
 *用法: searchInformation()
 *--------------------------
 *这个方法用来在文件中查找某个员工的信息。首先我们用readCodeFile函数
 *将文件装进map中,然后将文件的查找转换为map中的查找,这也是为什么我在
 *addInformation()中一定要输入一个信息换行,这样就可以好好的利用map。 
 *map<string,string>,前面是标签,后面是便签对应的内容。 staffNumbers是
 *map<string,string>的一个对象,staffNumbers[numbers]代表的是这个标签对应的
 *内容 
 */ 
void ManagmentSystem::searchInformation(){
    map<string,string> staffNumbers;
    ManagmentStaff msff;
    ManagmentStaff *msf = &msff;  
    readCodeFile(staffNumbers);
    while (true) {
        string numbers;
        cout << "要查找的员工工号(输入1停止输入): ";
        cin >> numbers;
        if (numbers == "1") {
            backToMenu(); 
            break;
        }
        if (isFind(staffNumbers,numbers)){
        cout << numbers << " " << staffNumbers[numbers] << endl;
        } else {
        cout << "找不到这位员工,是否添加这位员工的信息?(Y|N)" << endl;
        char ch;
        cin >> ch;
        if(ch == 'Y') {
            msf -> addInformation();
           }else{
             backToMenu(); 
           } 
        }   
    }
}
/*退出程序*/ 
void ManagmentSystem::quitSystem(){
    exit(0);
}
/*
 *方法:changeInformation
 *用法:changeInformation() 
 *修改员工信息。大致的操作与查找类似,先把文件装进map中,用map来处理字符
 *处理玩后我们再把map的内容再次输入文件。isFind函数用来判断是否找到对应的
 *标签,这里指的是工号。 
 *
 */ 
void ManagmentStaff::changeInformation(){
    map<string,string> staffNumbers;
    readCodeFile(staffNumbers);
    while(true){ 
    cout << "输入你想修改的工号" << endl;
    string numbers;
    cin >> numbers; 
    if(numbers.length() != 4) cout << "请输入4位数的工号" << endl;
    if(!isFind(staffNumbers,numbers)) cout << "工号有误,重新输入" << endl;
    cout << "该工号的信息为: " << endl;
    cout << numbers << " " << staffNumbers[numbers] << endl;
    cout << "请输入你想修改的内容(修改工号输入0,其他输入1):" << endl;
    int i; cin >> i;
    if(i == 0) {
        string str; cin >> str;
        numbers = str;
        cout<< "修改成功" << endl; //相当于修改map标签 
    }else{
        cout <<"修改格式为:姓名,年龄,工资" << endl;
        string line;
        cin >> line;
        staffNumbers[numbers] = line; /*将字符串line的信息覆盖以前的numbers
                                        标签对应的信息*/ 
        cout<< "修改成功" << endl; 
      }
      cout << "继续修改请输入0,保存并返回菜单输入1" << endl;
      int k; cin >> k;
      if(k == 1){
            break;
      } 
    } 
    ofstream outfile;
    outfile.open("F:\\my.txt",ios::out);
    map<string,string>::iterator it;
    /*迭代器从头到尾开始遍历,it->first表示指向的内容是标签,second指的是内容*/ 
    for(it = staffNumbers.begin(); it != staffNumbers.end(); it++)
    outfile << (it -> first) << "=" << (it -> second) << endl;

}
/*方法:deleteInformation 
 *用法:deleteInformation() 
 *------------------------- 
 *删除员工的信息,处理方式与上述的两种相同
 *iterator迭代器(你可以看为指针),staffNumbers.find(numbers),在map中
 *查找是否有这样的标签,有的话就返回标签的地址,staffNumbers.erase(it);
 *这个方法删除对应地址的map值。 
 */ 
void ManagmentStaff::deleteInformation(){
    map<string,string> staffNumbers;
    readCodeFile(staffNumbers);
    while(true){ 
    cout << "输入你想删除的员工的工号" << endl;
    string numbers;
    cin >> numbers; 
    if(numbers.length() != 4) cout << "请输入4位数的工号" << endl;
    if(!isFind(staffNumbers,numbers)) cout << "工号有误,重新输入" << endl;
    map<string,string>::iterator it;
    it = staffNumbers.find(numbers);
    staffNumbers.erase(it);
    cout << "继续删除请输入0,保存并返回菜单输入1" << endl;
      int k; cin >> k;
      if(k == 1){
            break;
      } 
   }
    ofstream outfile;
    outfile.open("F:\\my.txt",ios::out);
    map<string,string>::iterator it;
    /*迭代器从头到尾开始遍历,it->first表示指向的内容是标签,second指的是内容*/ 
    for(it = staffNumbers.begin(); it != staffNumbers.end(); it++)
    outfile << (it -> first) << "=" << (it -> second) << endl;
    backToMenu();//返回菜单 
}

/*判断输入的指令是否有误*/ 
bool isRightCommand(char ch){
    switch(ch){
        case 'd': case 's': case 'e': case 'a': case 'q':
        case 'D': case 'S': case 'E': case 'A': case 'Q':
            case 'C': 
            return true;
            default:
                return false;
    }
}
/*
 *函数: isFind
 *用法: if(isFind(mymap,code))
 *---------------------------------- 
 *判断是否能在map中找到这样的标签
 *能找到就返回这个标签的地址,不能就返回map中的最后一个元素的后一个地址
 *也就是end()方法对应的地址
 */
bool isFind(map<string,string> mymap, string code){
    map<string,string>::iterator it;
    it = mymap.find(code);  
    if(it == mymap.end()) return false;
    return true; 
} 
/*将文件读取到map中 */
void readCodeFile(map<string,string> & mymap){
    ifstream infile;
    infile.open("F:\\my.txt");
    if (infile.fail()) {
    cout << "读取文件失败";
    exit(1);
    }
    while (true) {
        string line;
        getline(infile, line);
        if (infile.fail()) break;
        if (line.length() < 5 || line[4] != '=') {
        cout << "不合法的输入" << endl; 
}
        string code = line.substr(0, 4);//因为你工号是4位数所以截取信息的前四个 
        mymap[code] = line.substr(5);//截取5以后的字符串都赋值给code作为map内容 
}
        infile.close();
} 
/*返回菜单*/ 
void backToMenu(){
    ManagmentSystem mst;
    ManagmentSystem *ms = &mst;
    ms -> menu();   
}

这里用到的主要是将文件装进map中处理,然后再将处理完的map写回文件中。满足要求中数据用文件存储。这里到了好技巧。

测试代码:

#include <iostream>
#include "Managment.h"
using namespace std;
int main(){
    ManagmentSystem ms;
    ms.welcomeInformation();
    ms.menu();
    return 0;
}

运行代码:

“`
C++抽象编程——简单的员工信息管理系统
编译通过!
C++抽象编程——简单的员工信息管理系统
运行示例。

虽然时间匆忙但是大多数功能也还算实现了。写完成就感慢慢,虽然你还有诸多bug,有时间慢慢调。大家有好的想法也可以说说。我把代码贴出来就是希望我们大家能相互学习