我们专业大二下学期C++综合训练的作业是资助选题做一个简单的管理系统,我选了第一个,完成后心想着还是发一篇博客吧,毕竟自己还是研究了很久。
话不多说,我们先看一下题目吧:
课题名称:工资管理
说明:一个员工工资管理程序,有新建、存储、显示、修改和删除的功能。
要求:
1) 利用工号区别员工身份,工号用字符数组的形式,从000001开始编号,该工号不能人工修改,是由计算机自动根据录入的先后复制的,录入数据时不必输入工号。
2) 可以选择现实的多种排序形式,如按姓名的顺序、工资总额的顺序、职务工资或奖金的顺序。
3) 每次显示时,将所有要显示数据的工资总额、职务工资总额、奖金总额一起计算显示。
4) 可以根据工号或姓名修改、删除数据,在修改、删除时现要求用户确认,确认后再进行操作。
题目要求必须使用到文件流或者数据库,并且如果使用字符界面的话还要自己用符号堆砌一个界面出来。
接下来就说一下我的整体思路:
建立结构体-->因为我们要从文本文件中读出数据,为了使读出的数据能够规范显示在字符界面上,我们也需要定义规范输出数据的函数-->建立字符界面(提示用户输入数据)-->使用if...else...对输入进行处理(就是调用不同函数)-->逐个实现函数,实现的函数主要包括:插入员工,删除员工,查找员工(查找所有,根据工号查找,修改职工信息,根据名字查找,按照工资对员工进行排序)
为避免出错,我们先include:
#pragma once #include<iostream> #include<iomanip> #include<string> #include<fstream> #include<sstream>建立结构体:
建立的结构体内部包括:员工的ID,员工姓名,员工工资,奖金,总工资,后面对文件的操作都会用到,
员工的id我使用的是int型,只不过输出的时候我们可以通过前面补0的方式来实现工号的规范性
//=================================================结构体========================================= struct workerInfo { int workerID; string workerName; int totoalSalary; int jobSalary; int bonus; }; 设计规范输出的函数:
//将查询到的对象转化为可输出形式 void txttoString(int id,string name, int salary, int bonus, int total) { cout << setw(8) << " 工号: " << setw(6) << setfill('0') << id << setw(8) << setfill(' ') << " 姓名: " << setw(6) << setfill(' ') << name << setw(8) << setfill(' ') << " 工资总额: " << setw(6) << setfill(' ') << salary << setw(8) << setfill(' ') << " 奖金: " << setw(6) << setfill(' ') << bonus << setw(8) << setfill(' ') << " 职务工资: " << setw(6) << setfill(' ') << total << endl; }设计字符界面:
提示用户输入按什么键就可以执行什么操作,例如增删查改,如下:
//===========================================================窗口化界面======================================================== void view() { system("cls"); cout << " //-----------------------------------------管理系统-----------------------------------------//" << endl; cout << " " << endl; cout << " " << endl; cout << " //==========================================================================================//" << endl; cout << " // //" << endl; cout << " // //" << endl; cout << " // //" << endl; cout << " // 请选择需要的操作: //" << endl; cout << " // 1、添加职工 //" << endl; cout << " // 2、删除职工 //" << endl; cout << " // 3、更改职工信息 //" << endl; cout << " // 4、根据ID查找职工 //" << endl; cout << " // 5、查询所有职工 //" << endl; cout << " // 6、按工资给职工排序 //" << endl; cout << " // 7、根据名字查找职工信息 //" << endl; cout << " // 其他、退出系统 //" << endl; cout << " // //" << endl; cout << " // //" << endl; cout << " // //" << endl; cout << " //==========================================================================================//" << endl; }效果:
然后就使用if...else...语句对输入内容执行调用函数,如下:
//===========================================================总入口============================================================ void init() { while (true) { view(); int Number; cin >> Number; if (Number == 1) { Insertinfo(); } else if (Number == 2) { DeleteWoker(); } else if (Number == 3) { updateWorker(); } else if (Number == 4) { selectByID(); } else if (Number == 5) { selectAll(); } else if (Number == 6) { orderByWorkerSalary(); } else if (Number == 7) { selectByName(); } else { cout << "退出系统" << endl; break; } system("pause"); } }接下来要做的就是逐个实现所有函数:
增添员工:
/* *插入职工信息--ok *寻找最大的工号,创建员工的时候在这个工号上加一 *从文件尾部开始插入字符串 *提示用户输入员工相关信息 *然后将该行读取到文本文件中 *文件中每一行就相当于一个结构体,结构体每一个成员用空格隔开 */ void Insertinfo() { //寻找最大的工号,创建员工的时候在这个工号上加一,因为工号本身就是从小到大排列的,所以我们只需要找到最后一行的工号即可 int num = 0; //员工最大工号,初始化为0 char * ch = new char[80]; fstream out("WokerList.txt"); while (out.getline(ch, sizeof(workerInfo))) { stringstream s(ch); s >> num; } //cout << "s=" << num << endl; out.close(); //提示用户输入信息 fstream workeradd("WokerList.txt", ios::app); workeradd.ate; std::cout << "请输入姓名: " << endl; string name; cin >> name; std::cout << "请输入职业工资: " << endl; int salary; cin >> salary; std::cout << "请输入奖金: " << endl; int bonus; cin >> bonus; //总工资 int tmoney; tmoney = salary + bonus; //将数据读到文档中 workeradd << endl << num + 1 << " " << name << " " << salary << " " << bonus << " " << tmoney; cout << "插入成功" << endl; workeradd.close(); }效果:
txt文件是这样的:
删除员工:
/* *删除职工 *C++并没有提供删除文本某一行的函数, *所以我们的思路是:逐行扫描每行字符串,并将字符串分割并存储到结构体数组里面,遇见我们要删除的行时则不存储 *然后删除源文本文件,创建同名文本文档,将数组输入到文本文件里面 */ void DeleteWoker() { cout << "请输入职工号" << endl; int num; cin >> num; char * ch = new char[80]; bool flag = false; //我们可能会遇见我们找不到要删除的员工的情况,所以这里设置一个布尔值来判断 workerInfo *wokers = new workerInfo[20]; //创建一个数组,来存储信息,等会儿再把数组输入到新文件中 int i = 0; //用来统计列表的人数 //打开文件,存储除了要删除的职工以外的所有信息 string filename = "WokerList.txt"; ifstream wokerList(filename); while (wokerList.getline(ch, 80)) { int id, salary, bonus, total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; if (id != num) { wokers[i].workerID = id; wokers[i].workerName = name; wokers[i].jobSalary = salary; wokers[i].bonus = bonus; wokers[i].totoalSalary = total; i++; } else { flag = true; } } wokerList.close(); delete[] ch; if (!flag) { //没有找到员工 cout << "未找到该员工,删除失败" << endl; } else { //删除文件 system("del WokerList.txt"); //重新创建文件,与原文件名一样 ofstream newFile(filename, ios::in | ios::out); newFile.open(filename); for (int j = 0; j < i; j++) { newFile << wokers[j].workerID << " " << wokers[j].workerName << " " << wokers[j].jobSalary << " " << wokers[j].bonus << " " << wokers[j].totoalSalary << endl; } newFile.close(); cout << "删除成功" << endl; } delete[] wokers; }效果:
根据工号查找员工:
/* *根据id查找职工信息--ok *提示用户输入ID, *逐行查找文本,分割字符串并匹配 *如果找到就调用输出函数输出,否则输出“未查到该用户” */ void selectByID() { std::cout << "请输入职工号" << endl; bool flag = false; //判断是否找到元素 int num; cin >> num; char * ch = new char[200]; ifstream wokerList("WokerList.txt"); while (wokerList.getline(ch, sizeof(workerInfo))) { int id, salary, bonus, total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; if (id == num){ txttoString(id, name, salary, bonus, total); flag = true; break; } } if (!flag) { cout << "未找到该员工" << endl; } wokerList.close(); delete []ch; }效果:
根据名字查找员工:
/* *根据姓名查找职工信息--ok *提示用户输入姓名, *逐行查找文本,分割字符串并匹配 *如果找到就调用输出函数输出,否则输出“未查到该用户” */ void selectByName() { std::cout << "请输入职工姓名" << endl; bool flag = false; //判断是否找到元素 string wokername; cin >> wokername; char * ch = new char[200]; ifstream wokerList("WokerList.txt"); while (wokerList.getline(ch, sizeof(workerInfo))) { int id, salary, bonus, total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; if (wokername == name) { flag = true; txttoString(id, name, salary, bonus, total); } } if (!flag) { cout << "未找到该员工" << endl; } wokerList.close(); delete ch; }效果:
查询所有职工信息:
/* *查询所有职工信息--ok *逐行读取文本,分割字符串,调用输出函数,将分割的字符串输出 */ void selectAll() { char * ch = new char[80]; ifstream wokerList("WokerList.txt"); while (wokerList.getline(ch, 80)) { int id, salary, bonus, total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; txttoString(id, name, salary, bonus, total); } wokerList.close(); delete ch; }效果:
修改职工信息:
/* *修改职工信息--ok *思路:逐行扫描文本,分割字符串,全部存储再数组里面 *判断数组的对应字符,如果相等,则进入更改 * 更改过程:提示用户如何更改 * 删除源文本文件,重新创建同名文本文件 * 再将数组读取到文本里 *如果不相等,则继续扫描文本,知道扫完为止 * */ void updateWorker() { cout << "请输入职工号" << endl; bool flag = false; //判断是否找到元素 int num; cin >> num; char * ch = new char[80]; workerInfo *wokers = new workerInfo[20]; //创建一个数组,来存储信息,等会儿再把数组输入到新文件中 int i = 0; //用来统计列表的人数 int lineNumber; //用来确定目标行号 string filename = "WokerList.txt"; ifstream wokerList(filename); while (wokerList.getline(ch, 80)) { int id, salary, bonus, total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; wokers[i].workerID = id; wokers[i].workerName = name; wokers[i].jobSalary = salary; wokers[i].bonus = bonus; wokers[i].totoalSalary = total; if (id == num) { lineNumber = i; flag = true; } i++; } if (!flag) { cout << "未找到该员工" << endl; } else { //修改变量 cout << "请输入要修改的值:1、姓名,2、职业工资,3、奖金。其他:放弃操作" << endl; int num2; cin >> num2; if (num2 == 1) { cout << "请输入姓名" << endl; string Newname; cin >> Newname; wokers[lineNumber].workerName = Newname; } else if (num2 == 2) { cout << "请输入工资" << endl; int newSalrary; cin >> newSalrary; wokers[lineNumber].jobSalary = newSalrary; wokers[lineNumber].totoalSalary = newSalrary + wokers[lineNumber].bonus; } else if (num2 == 3) { cout << "请输入奖金" << endl; int newBonus; cin >> newBonus; wokers[lineNumber].bonus = newBonus; wokers[lineNumber].totoalSalary = newBonus + wokers[lineNumber].jobSalary; } else { cout << "放弃操作" << endl; wokerList.close(); delete ch; return; } wokerList.close(); //删除文件 system("del WokerList.txt"); //重新创建文件,与原文件名一样 ofstream newFile(filename, ios::in | ios::out); newFile.open(filename); for (int j = 0; j < i; j++) { newFile << wokers[j].workerID << " " << wokers[j].workerName << " " << wokers[j].jobSalary << " " << wokers[j].bonus << " " << wokers[j].totoalSalary << endl; } newFile.close(); cout << "修改成功" << endl; } delete[] ch; }效果:
文件内部:
对员工工资进行降序排序:这里使用的是冒泡排序
/* *按工资给职工排序--ok *思路:一行一行读取文本,再将读取到的每行字符串分割,存储到数组里面 * 然后将数组的内容进行排序再输出到界面 */ void orderByWorkerSalary() { workerInfo *array = new workerInfo[20]; char * ch = new char[80]; ifstream wokerList("WokerList.txt"); int k = 0,all = 0; while (wokerList.getline(ch, 80)) { int id,salary,bonus,total; string name; stringstream is(ch); is >> id >> name >> salary >> bonus >> total; workerInfo item; item.workerID = id; item.workerName = name; item.jobSalary = salary; item.bonus = bonus; item.totoalSalary = total; array[k] = item; k++; all++; } wokerList.close(); //冒泡排序 for (int j = 0; j < all-1; j++) { for (int k = 0; k < all; k++) { if (array[k].totoalSalary < array[k + 1].totoalSalary) { workerInfo m; m = array[k]; array[k] = array[k + 1]; array[k + 1] = m; } } } for (int j = 0; j < all; j++) { txttoString(array[j].workerID,array[j].workerName,array[j].jobSalary,array[j].bonus,array[j].totoalSalary); } delete ch; delete[] array; }效果:
最后只需要写一个main函数调用initial()即可:
#include "标头.h" int main() { init(); system("pause"); return 0; }然后整个管理系统就做好了,希望可以作为大家的参考,不足之处还望大佬指正!