本来打算今天要写的是快速排序的,那只能等明天了。因为今天突然有个老同学叫我帮她写一个简单的员工管理系统。我从下午3点写到6点30分(没办法,毕竟我也才大二)。最后大致写了个大概,我就把他们的题目拿出来一下吧

实际上我们学校是没有具体讲文件处理的。但是我之前谢写过我们可以用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;
}

运行代码:

“`

编译通过!

运行示例。

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

Logo

快速构建 Web 应用程序

更多推荐