1需求分析
1.1 问题描述
对单位的职工进行管理, 包括插入、 删除、 查找、 排序等功能。
1.2 问题要求
职工对象数不必很多, 便于一次读入内存, 所有操作不经过内外存交换。
(1) 由键盘输 入职工对象, 以文件方式保存。 程序执行时先将文件读入内存。
(2) 对职工对象中的"姓名"按字典顺序进行排序。
(3) 对排序后的职工对象进行增、 删、 查询、 修改、 排序等操作。
2总体设计
2.1 设计思路
该系统的功能大致为增删改查和排序,分别将这些功能在不同的函数中实现,主菜单为显示所有功能,并有一个修改数据的子菜单,这两个菜单可以来回切换,主菜单包括:
- 显示所有成员
- 注册员工
- 按姓名查询员工
- 按职务查询员工
- 按id删除员工
- 按姓名删除员工
- 按年龄对数据进行升序
- 按年龄对数据进行降序
- 按名字字典进行升序
- 按名字字典进行降序
- 修改员工信息
子菜单包括:修改员工id,性别,年龄,住址,职务,电话,工作年月,学历,以及修改全部,在修改全部功能中,类似于注册员工一样,只不过有些信息是一旦注册了就不能改变的,比如出生日期。
每回注册员工都会将数据写入文件,没回退出也会将程序执行的一系列修改的新数据写入文件,所以如果非正常方式退出可能会导致数据丢失。
对数据的录入进行限制,年龄只能在0-100,注册以及修改id不能重复,学历只能从提供的几个选项中进行选择,性别也是只有男女,出生年月注册时需要填写,年份会根据年龄进行计算,并进行相应的存储,工作时间会以当前注册的时间为工作时间并进行存储,工作时间也可人为修改,即进行重置,电话号码有位数要求,必须填写正确格式的电话号码。
如果进行命令选择的时候选择了错误的命令,系统提示指令物,请重新选择,如果输入的数据不符合要求,系统会提示数据不符合要求,请重新输入,按退出键时会提示是否真的要退出,在进行一次选择,指令错误依然会提示指令错误,对界面加一些装饰进行美化。
所以,根据上面的模型分析及输入输出参数分析,可以定义一种数据结构后进行算法实现。
2.2总体设计功能图
图2-1 总体功能图(5号字,按节编号,表示第2节第1个图)
3详细设计
对数据结构进行详细的描述, 设计好相应数据结构以及其操作功能, 要求用C或C++; 用文字详细描述每个功能实现的算法及思路。画出各函数的调用关系图。模块功能说明(如函数功能、入口及出口参数说明,函数调用关系描述等)
3.1抽象数据类型定义
数据对象:员工id,员工名字,员工年龄,员工性别,员工出生日期,员工工作日期,员工住址,员工所在部门,员工电话号码,以及指向下一个对象的类指针。
数据关系:所有的数据对象封装到一个类中,,每个成员都会指向下一个成员。
基本操作:对对象进行查找,删除,修改,增加,将所有对象进行排序,将对象中的数据写入文件,将数据从文件中读取到内存中。
3.2存储结构设计
链式存储结构
3.3算法设计
自然语言描述
(1)对链式结构的查找
(2)对链式结构的排序
(3)对链式结构的删除
(4)对链式结构的增加
(5)对链式结构的修改
流程图描述
查找
排序
删除
增加
修改
4代码实现
4.1 函数清单
列出所有编写的函数清单,说明每个函数的功能,函数形式参数的设置及意义
staff() : next(NULL) {}
void registeration(class staff *head);//注册员工
void query_name(class staff *t);//按名字查找
void query_depart(class staff *t);//按部门查找
void delete_num(class staff *t);//按id删除
void delete_name(class staff *t);//按名字删除
void show_all(class staff *head);//显示所有数据
void update(class staff *head);//更新所有数据(子菜单)
void update_num(class staff *head);//修改员工的id
void update_name(class staff *head);修改员工的名字
void update_age(class staff *head);//修该员工的年纪
void update_sex(class staff *head);//修改员工的性别
void update_study(class staff *head);//修改员工的学历
void update_work(class staff *head);//修改员工的工作日期
void update_address(class staff *head);//修改员工的住址
void update_depart(class staff *head);//修改员工的部门
void update_phone(class staff *head);//修改员工的电话号码
void update_all(class staff *head);//修改所有数据
void sort_up(class staff *head);//按年龄升序
void sort_down(class staff *head);//按年龄降序
void sort_nup(class staff *head);//按名字字典升序
void sort_ndown(class staff *head);//按名字字典降序
int read(class staff *head);//读文件
void write(class staff *t);//写文件
**4.2 主函数 **
主函数代码
#include <iostream>
#include <string>
#include <fstream>
#include "staff.cpp"
//#include "staff.h"
using namespace std;
int main()
{
staff *head = new staff;
head->read(head);
string temp;
cout << "简单的职工管理系统--课程设计" << endl;
while (1)
{
cout << "--------1.显示所有成员--------------------------------------------------" << endl;
cout << "--------1.注册员工id(注册完毕后默认按名字字典升序存储在文件中)--------" << endl;
cout << "--------2.按照姓名查询员工信息------------------------------------------" << endl;
cout << "--------3.按照职务查询员工信息------------------------------------------" << endl;
cout << "--------4.按id删除员工信息----------------------------------------------" << endl;
cout << "--------5.按姓名删除员工信息--------------------------------------------" << endl;
cout << "--------6.按年纪升序排列------------------------------------------------" << endl;
cout << "--------7.按年纪降序排列------------------------------------------------" << endl;
cout << "--------8.修改员工信息--------------------------------------------------" << endl;
cout << "--------9.按名字字典升排序----------------------------------------------" << endl;
cout << "--------10.按名字字典降排序---------------------------------------------" << endl;
cout << "--------11.生成排序数据---------------------------------------------" << endl;
cout << "--------0.退出----------------------------------------------------------" << endl;
cout << endl;
cout << "请输入你想选择的功能:" << endl;
int number;
cin >> number;
switch (number)
{
case -1:
{
head->show_all(head);
break;
}
case 1:
{
head->registeration(head);
head->sort_nup(head);
head->write(head);
break;
}
case 2:
{
head->query_name(head);
break;
}
case 3:
{
head->query_depart(head);
break;
}
case 4:
{
head->delete_num(head);
head->write(head);
break;
}
case 5:
{
head->delete_name(head);
head->write(head);
break;
}
case 6:
{
head->sort_up(head);
head->write(head);
cout<<"排序完成------------------"<<endl;
cout<<"是否显示排序过后的数据:(1.是/0.否)";
int x;
cin>>x;
if(x==1){
head->show_all(head);
cout<<"排序完成------------------"<<endl;
}
else{
cout<<"排序完成------------------"<<endl;
}
break;
}
case 7:
{
head->sort_down(head);
head->write(head);
cout<<"排序完成------------------"<<endl;
cout<<"是否显示排序过后的数据:(1.是/0.否)";
int x;
cin>>x;
if(x==1){
head->show_all(head);
cout<<"排序完成------------------"<<endl;
}
else{
cout<<"排序完成------------------"<<endl;
}
break;
}
case 8:
{
head->update(head);
head->sort_nup(head);
head->write(head);
break;
}
case 9:
{
head->sort_nup(head);
head->write(head);
cout<<"排序完成------------------"<<endl;
cout<<"是否显示排序过后的数据:(1.是/0.否)";
int x;
cin>>x;
if(x==1){
head->show_all(head);
cout<<"排序完成------------------"<<endl;
}
else{
cout<<"排序完成------------------"<<endl;
}
break;
}
case 10:
{
head->sort_ndown(head);
head->write(head);
cout<<"排序完成------------------"<<endl;
cout<<"是否显示排序过后的数据:(1.是/0.否)";
int x;
cin>>x;
if(x==1){
head->show_all(head);
cout<<"排序完成------------------"<<endl;
}
else{
cout<<"排序完成------------------"<<endl;
}
break;
}
case 11:
{
head->hahaha(head);
head->write(head);
cout<<"数据生成完毕"<<endl;
break;
}
case 0:
{
char sign;
cout << "是否要退出(y/n)?";
cin >> sign;
switch (sign)
{
case 'y':
{
head->write(head);
return 0;
}
case 'n':
{
break;
}
default:
cout << "请输入正确的指令" << endl;
continue;
}
}
default:
cout << "请输入正确的指令" << endl;
}
}
//system("chcp 65001");
}
4.3 其他函数
读写文件的函数操作,自动生成数据的函数操作,在staff.cpp中实现。
5运行与测试
针对不同情况列出对应的输入和输出,用有代表性的例子说明程序完成了设计任务和目标。
(1)正常测试数据和运行结果
(要求提供正常测试数据和运行结果,根据题目的功能选择几组)
程序开始执行,显示了菜单,输入-1,因为此时文件里没有任何数据,所以数据的内容为一各成员也没有,快来添加一个吧
,输入1,进行数据的注册,跟着程序的提示一步一步进行输入,输入过程中如果了不符合格式的数据,会被要求重新输入此选项,知道输入正确地格式,才能进行下一个数据的输入,重复录入多组数据后,这些数据会被保存在文件中,以便下一次程序执行来读取,然后执行查找操作,根据名字或职务都能对应显示相应的数据,一组或多组,执行排序操作,根据id或名字字典都能进行正确地排序,并显示排序过的新数据,退出程序后,文件里数据顺序发生相应的变化(输入11,可以自动生成数据,来进行排序测试),执行删除操作,根据id或姓名进行删除可以正常执行。
执行修改操作首先输入8,进入修改页面,进行进一步选择,选择单个信息进行修改,id不能修改为重复的,其余的数据修改格式若修改格式不正确也会提示让重新输入。进入修改全部会对一个成员的信息进行全部修改,都会对应进行正确地修改。
下面来看一下测试:
注册员工:
删除员工
查找
按名字字典排序
修改数据
(2)异常测试数据及运行结果
(要求提供 几组异常测试数据和运行结果)
异常数据:
当输入重复id时,会显示,id会已存在,当交替进行这个错误操作,会出现已存在的id允许被录入,比如:输入1(id已存在),在输入2(id已存在),都会显示id已存在,请重新输入,但在输入1时,这个id却可以被录入。
异常分析:
这样的原因是是由于,每次判断完id后,指向该id的指针,还指向该id,就导致了如果下一个输入的id若在此id后面,会将指针后移,然而在输入该id前面的,虽然该id已存在,但由于判断指针无法再是指向该id,导致这个bug的产生。
解决方法:
在函数开始出定义一个永远指向头结点的指针,每次判断完毕后,将判断指针指向该永久指向头结点的指针,这样一来就可以避免漏掉已经判断过的id。
注:改程序依然存在一个小bug,但不影响整体功能!
那就是,虽然输入错误的指令,选择错误的选项会让重新输入,并可以一直循环下去,知道用户输入正确的位置,但有一处选择功能,就是选择(y/n) 的时候,若果不按照要求输入,会出现死循环,这里的不按照要求是指,输入了多个字符,原因是,写代码时,在这里加的判断使用char判断的,所以如果多输了字符,多出来的另一个字符就会导致循环一直执行下去,其实我当时应该字符串判断的,但我后后悔当初没这么做,现在想改已经来不及了,因为今天就要交了,而我是今天测试时才发现的,有点尴尬,但这个bug我后面一定会修复这个bug。
♻️ 资源
大小: 3.76MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87248047