C++抽象编程——简单的员工信息管理系统
程序员文章站
2022-04-10 23:40:03
...
本来打算今天要写的是快速排序的,那只能等明天了。因为今天突然有个老同学叫我帮她写一个简单的员工管理系统。我从下午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,有时间慢慢调。大家有好的想法也可以说说。我把代码贴出来就是希望我们大家能相互学习