公司员工管理系统

《高级语言程序设计》作业报告

作业名称: 公司员工管理系统

学 院 专 业 学生姓名 任课教师

提交日期 2014年6月27日

一、 问题描述

一间公司有各种人员,对人员信息的管理显得比较重要。于是,本系统是要

解决公司员工信息的管理。主要有信息的增加,查询,删除,更新等操作。解决了人员的增加,减少,变更等的情况。 二、

系统设计

1、类体系设计:

设计一个员工虚基类staff ,包含编号、姓名和年龄保护数据成员,还有相关的函数。因为公司里面人员的分类众多,难以找到统一标准,在此进行简化,暂且将人员分为管理方面和研究方面。所以,从基类中派生出研究人员类engineer, 里面增加专业,职称两个保护数据成员。同样地,管理类leader 也从基类派生,里面增加职位,部门两个保护数据成员。考虑到有的员工同时具有这两个性质,即同时兼有管理和研究的职责,于是从研究类和管理类中派生出研究管理类chairman ,该类属于多继承了前面的两个类。现在已经有四个类,而且它们具有继承关系。接着要考虑对数据的操作和对各种员工的管理操作,另外定义一个员工管理类staffmanage ,将各种操作函数,数据成员进行封装。至于各个类的成员函数都有自己的版本,利用多态性,用基类指针指向派生类对象进行调用。 2、数据结构分析

因为涉及到信息的处理,所以采用二进制文件staff.dat 保存数据。上述的类体系中,不同类层次的对象具有的数据成员不同,为了方便存储在一个二进制文件中并且能进行查询等操作,另外建立索引结构indextype ,并将索引存储在索引文件index.dat 中。索引结构中必须包含一个数据成员position 记录不同对象数据在二进制文件的相对存储位置。另外,查找数据的标志设置为人员的编号num ,为了便于进行删除操作,设删除标记deltag.

最后,文件操作时要确定写入的文件大小,需要有人员类型标记stafftypeb 便于分配存储空间。 3、类定义及成员函数功能描述:

虚基类staff :

class staff {

public:

staff(){} //构造函数 virtual~staff(){} //虚析构函数 const char*getnum()const{return num;} //返回编号 virtual void input()=0; //输入函数 virtual void show()const=0; //显示数据 virtual void read(fstream &f)const=0; //读文件 virtual void write(fstream &f)const=0; //写文件 protected:

char num[8]; //编号 char name[12];//姓名 int age; //年龄 }

该基类把员工的基本数据成员和基本操作都包含进来了。除了返回编号的函数有具体实现,其他函数都声明为纯虚函数。 研究人员类engineer

class engineer:virtual public staff {

public:

engineer(){} //构造函数 virtual~ engineer(){} //虚析构函数 void input(); //输入数据 void show()const; //显示数据 void read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(engineer)); };

void write(fstream &f)const //写文件 {

f.write((char*)this,sizeof(engineer)); };

protected:

char major[12]; //专业 char prof[12]; //职称 };

该类增加两个成员以记录更多的性质,函数也会给出具体实现,这里部分函数只做了声明。 管理人员类leader:

class leader:virtual public staff {

public:

leader(){}//构造函数

virtual~leader(){}//虚析构函数 void input();//输入数据

void show()const // 显示数据 { //显示信息

coutvoid read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(leader)); };

void write(fstream &f)const {

f.write((char*)this,sizeof(leader)); };

protected: //数据成员 char job[12]; //职务 char dep[12]; //部门 }

同样,管理人员类也声明了函数并给出了实现,增加了职务和部门两个数据成员。

管理及研究人员类chairman :

class chairman:public engineer,public leader {

public:

chairman(){} //构造函数 virtual~chairman(){} //虚析构函数 void input(); //输入数据 void show()const // 显示数据 void read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(chairman)); };

void write(fstream &f)const //写文件 {

f.write((char*)this,sizeof(chairman)); };

该类继承了engineer 类和leader, 包含前两者的数据成员并且有自己版本的函数实现。

员工管理类manage: class staffmanage {public:

staffmanage(); //构造函数 virtual~staffmanage(); //虚析构函数 void run(); //菜单函数 private: //私有成员 fstream file; //人员数据文件 indextype*indextable ; //索引表

int maxsize; //最大索引项个数 int count; //索引项个数

void addindexitem(const indextype &e); //在索引表中增加索引项 void adddata(); //增加数据 void updatedata(); //更新数据 void searchdata(); //查询数据

void deledata(); //删除数据,只作删除标记 void pack(); //在物理上删除作有删除标记的纪录

};

该类统一了对数据文件的操作。数据成员有数据文件,索引表定义为动态的,还有索引项个数的记录和一个最大索引项限制。

4、程序流程图:

三、程序测试

1、 登录模块

密码正确即可,初始密码为zxw, 有3次输入机会 2、 初始界面

菜单简单,操作方便 3、 增加数据

在测试时输入三组不同数据,操作均有提示,最后按‘q’返回主界面。

4、 查询操作

按照编号查找,找到后输出数据。 5、 删除操作:

按照编号查找,显示成功删除的操作。 6、 修改数据:

按编号查找,之后进行修改,人员类型是否改变会有不同的操作。 7、 重组数据:

为了充分利用存储空间,在数据文件中的作有删除标记的数据要被删除。 8、 退出:选择‘6’即可退出。 四、使用说明

本系统操作很简单,按照它的说明进行操作就行。先要输入密码才能登录系统。菜单的前五个功能可以反复执行。 五、程序的改进及bug:

本程序相对比较简单,很多功能都很粗糙。比如不可以修改密码,比如不可以输入其他的数据。还有,对员工分类过于简单。这些确实可以逐渐完善,鉴于系统的完成时间有限,就没有优化。调试过程中发现一个BUG ,再次打开程序查找先前输入的数据时会出现异常,异常信息如下:

问题签名:

问题事件名称: APPCRASH 应用程序名:

公司员工管理系统.exe

应用程序版本: 0.0.0.0 应用程序时间戳:

53a6719d

故障模块名称: 公司员工管理系统.exe 故障模块版本:

0.0.0.0

故障模块时间戳: 53a6719d

异常代码: c0000005 异常偏移: 0001e72d

OS 版本: 6.1.7601.2.1.0.256.1 区域设置 ID: 其他信息 1: 其他信息 2: 其他信息 3: 其他信息 4:

2052 0a9e

0a9e372d3b4ad19135b953a78882e789 0a9e

0a9e372d3b4ad19135b953a78882e789

于是我一直查找异常的原因,估计是第二次运行的时候,初始化文件时,文件数据读入文件流时的绝对位置发生了改变。尝试修改程序,但是遗憾的是直至撰写报告的时候,我还是没有解决到问题。从这个过程中我深刻地感受到自己所懂得的实在是太少了。有一个BUG 实在很遗憾。其中也有自己写程序是大局观不够,没有全盘考虑有关。 六、收获与体会

1、这次的课程设计真的充分暴露了我的不足,很多东西都要不断查资料,而且平时编程没有养成好的习惯,编写速度比较慢。还有,收获也是比较大的,特别是对于文件处理这一方面,具体的定位,读写等都有了进一步的了解。对于类体系的设计,也要求考虑很多东西,锻炼了将问题解决的能力。

2、积累了经验,懂得了要编写较大的程序时要先有一个大体的想法框架,然后逐步完成,有点像逐步求精法一样。只要大的框架没有错,后面即使有错误都只是局部的错误,容易改正。

3、锻炼了耐心,有时候小错误要找很久。甚至找几天都找不到,确实很需要静下心来

慢慢找。

4、认识到自己的不足,很多都是要查阅资料,甚至有一个BUG 没法解决,导致本系统未能完成。虽然未能解决,但是寻求解决办法的过程中也学到很多东西,特别是对tellg()、seekg()这两个函数的了解,还有一些别人的经验。

附:完整程序

// C++大作业.cpp : 定义控制台应用程序的入口点。

//

#include

#include

#include

#include

#include

#define increament 1000 //增量

using namespace std;

//员工类

class staff

{

public:

staff(){} //构造函数

virtual~staff(){} //虚析构函数

const char*getnum()const{return num;} //返回编号

virtual void input()=0; //输入函数

virtual void show()const=0; //显示数据

virtual void read(fstream &f)const=0; //读文件

virtual void write(fstream &f)const=0; //写文件

protected:

char num[8];

char name[12];

int age;

};

//研究人员类

class engineer:virtual public staff

{

public:

engineer(){} //构造函数

virtual~ engineer(){} //虚析构函数

void input() //输入数据

{ //输入相关信息

cout

cin>>num;

} cout>name; cout>age; cout>major; cout>prof; void show()const // 显示数据 { //显示信息 coutvoid read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(engineer));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(engineer));

};

protected:

char major[12];

char prof[12];

};

//管理人员类

class leader:virtual public staff

{

public:

leader(){}//构造函数

virtual~leader(){}//析构函数

void input()

{ //输入相关信息

cout

cin>>num;

cout

cin>>name;

cout

cin>>age;

cout

cin>>dep;

cout

cin>>job;}

void show()const // 显示数据

{ //显示信息

cout

};

void read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(leader));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(leader));

};

protected: //数据成员

char job[12]; //职务

char dep[12]; //部门

};

//管理及研究人员类

class chairman:public engineer,public leader

{

public:

chairman(){} //构造函数

virtual~chairman(){} //虚析构函数

void input()

{ //输入相关信息

cout

cin>>num;

cout>name; cout>age; cout>dep; cout>job;

cout

cin>>major;

cout

cin>>prof;

}

void show()const // 显示数据

{ //显示信息

cout

};

void read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(chairman));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(chairman));

};

};

//索引结构

struct indextype

{

bool deltag; //删除标记

char num[8]; //编号

int position; //在数据文件中的相对位置

char stafftype; //人员类型

};

class staffmanage

{public:

staffmanage() //构造函数

{

ifstream indexfile("idx.dat",ios::binary); //建立输入索引文件

if(!indexfile.fail())

{ //打开文件成功

indexfile.seekg(0,ios::end); //定位

count=indexfile.tellg()/sizeof(indextype); //索引项个数

maxsize=count+increament ; //索引表最大索引项个数

indextable=new indextype[maxsize]; //为索引表分配储存空间 indexfile.seekg(0,ios::beg); //定位

int i=0; //临时变量

indexfile.read((char*)&indextable[i++],sizeof(indextype));//读记录

while(!indexfile.eof()) //文件未结束时

{

indexfile.read((char*)&indextable[i++],sizeof(indextype)); //读记录

}

indexfile.close(); //关闭文件

}

else //打开文件失败

{

count=0; //索引项个数

maxsize=count+increament; //索引表最大索引项个数

indextable=new indextype[maxsize]; //分配储存空间

}

ifstream ifile("staff.dat"); //建立输入文件

if(ifile.fail()) //打开文件失败,表示不存在文件

{

ofstream ofile("staff.dat"); //建立输出文件

if(ofile.fail()) throw("打开文件失败!"); //抛出异常

ofile.close(); //关闭文件

}

else

{

ifile.close(); //关闭文件

}

file.open("staff.dat",ios::in|ios::out|ios::binary); //以读写方式打开文件

if (file.fail()) throw("打开文件失败!"); //抛出异常

}

virtual~staffmanage() //虚析构函数

{

ofstream indexfile("idx.dat",ios::binary); //建立输出索引文件

for(int i=0;i

{

indexfile.write((char*)&indextable[i],sizeof(indextype)); //写文件

}

indexfile .close(); //关闭文件

file.close(); //关闭文件

}

void run(); //处理菜单

private: //私有成员

fstream file; //人员数据文件

indextype*indextable ; //索引表

int maxsize; //最大索引项个数

int count; //索引项个数

void addindexitem(const indextype &e); //在索引表中增加索引项

void adddata(); //增加数据

void updatedata(); //更新数据

void searchdata(); //查询数据

void deledata(); //删除数据,只作删除标记

void pack(); //在物理上删除作有删除标记的纪录

};

void staffmanage::adddata() //增加数据

{

staff*pstaff; //人员

indextype item; //索引项

item.deltag=false; //删除标记

file.seekg(0,ios::end); //定位

char answer; //临时变量

do

{

do

{

cout

cin>>item.stafftype; //输入人员类型

item.stafftype=tolower(item.stafftype);

转换为小写字母

}while(item.stafftype!='e'&&item.stafftype!='l'&&item.stafftype!='c');

if(item.stafftype=='e')

pstaff=new engineer; //分配存储空间

else if(item.stafftype =='l')

pstaff=new leader; //分配存储空间

else pstaff=new chairman; //分配存储空间

pstaff->input(); //输入数据

strcpy_s(item.num,pstaff->getnum()); //复制编号

item.position=file.tellg(); //写入数据文件的位置

addindexitem (item); //在索引表增加索引项

pstaff->write(file); //写文件

delete pstaff; //释放存储空间

cout

cin>>answer; //输入选择

}

while(answer=='y');

cout

cout

char answer1;

cin>>answer1;

if(answer1=='q')

{

system("cls");

}

}

void staffmanage::addindexitem(const indextype &e) //在索引表中增加索引项

{

if(count>=maxsize) //索引表溢出

{

maxsize=maxsize+increament; //增加索引表容量

indextype*tmpindextable=new indextype[maxsize];//临时索引表

for(int i=1;i

} { tmpindextable[i]=indextable[i]; } delete []indextable; //释放索引表的存储空间 indextable=tmpindextable; // 指向临时索引表 } indextable[count++]=e; //加入到索引表中

void staffmanage::deledata () //删除数据

{

staff*pstaff; //人员

indextype item; //索引项

item.deltag=false; //删除标记

char num[12]; //临时变量

cout

cin>>num; //输入编号

int pos; //临时变量

for(pos=0;pos

{

if(strcmp(num,indextable[pos].num)==0&&!indextable[pos].deltag) //查找索引项位置

break;

}

if(pos

{

file.seekg(indextable[pos].position,ios::beg); //定位 if(indextable[pos].stafftype=='e') pstaff=new engineer; //分配存储空间 else if(indextable[pos].stafftype=='l') pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->read(file); //读文件 coutshow(); //显示信息 indextable[pos].deltag=true; //置删除标记 delete pstaff; //释放存储空间 cout

char answer; //临时变量

cin>>answer; //接受输入

if(answer=='q')

{

system("cls"); //使用清屏函数

}

}

void login(int &loginsuccess) //登录函数

{

cout

cout

for (int i = 0; i

{

char code[10];

cout

cin>>code;

if (strcmp("zxw",code)==0) //判断密码是否正确

{

cout

loginsuccess=true; //给登录标志置值

break;

}

cout

}

void staffmanage::run() //数

{

int select; //码

do

{

cout

cout

cout

cout

cout

cout

cout

cout

选择操作函选择菜单号

} cin>>select; //输入选择 while(cin.get()!='\n'); switch(select) { case 1: } adddata (); //增加数据 break; updatedata(); //更新数据 break; searchdata (); //查询数据 break; deledata(); //删除数据 break; pack(); //在物理上删break; case 2: case 3: case 4: case 5: 除作有删除标记的纪录 while(select!=6); //选择6时退出

}

oid staffmanage::searchdata() //查询人员

{

staff*pstaff; //人员

char num[12]; //临时变量

cout

cin>>num; //输入编号

int pos; //人员编号

for(pos=0;pos

{

if(strcmp(num,indextable[pos].num)==0&&!indextable[pos].deltag)

break;

}

if(pos

{

file.seekg(indextable[pos].position,ios::beg); //定位

if(indextable[pos].stafftype=='e')

pstaff=new engineer; //分配存储空间

else if(indextable[pos].stafftype=='l')

pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->read(file); //读文件 pstaff->show(); //显示数据 delete pstaff; //删除存储空间 } else { cout>answer; //接受输入 if(answer=='q') {

system("cls"); //使用清屏函数 }

void staffmanage::updatedata () //更新数据

{

staff*pstaff; //人员 indextype item; //索引项 item.deltag=false; //删除标记 char num[12]; //临时变量 cout>num; //输入编号 int pos; //临时变量 for(pos=0;posread(file); //读文件 pstaff->show(); //显示数据 do

";

cout>item.stafftype; //输item.stafftype=tolower(item.stafftype); //转换 入人员类型

为小写字母

}while(item.stafftype!='e'&&item.stafftype!='l'&&item.stafftype!='c'); if(item.stafftype =='e') pstaff=new engineer; //分配存储空间 else if(item.stafftype =='l') pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->input(); //输入数据 if(item.stafftype==indextable[pos].stafftype ) { strcpy_s(indextable[pos].num,pstaff->getnum()); //复制编号 file.seekg(indextable[pos].position,ios::beg); //定位 } else { indextable[pos].deltag=true; //删除标记 strcpy_s(item.num,pstaff->getnum()); //复制编号 file.seekg(0,ios::end); //定位 item.position=file.tellg(); //写入文件的位置 addindexitem (item); //增加索引项 } pstaff->write (file); //写文件 delete pstaff; //删除存储空间 cout>answer; //接受输入 if(answer=='q') { system("cls"); //使用清屏函数 }

}

void staffmanage::pack() //重组文件 {

if(indextable[pos].stafftype=='e') pstaff=new engineer; //分配存储空间 else if(indextable[pos].stafftype=='l') ofstream ofile("tem.dat") ; //建立输出文件 ofile.close(); //关闭文件 fstream outfile("tem.dat",ios::app|ios::binary); //打开文件 staff*pstaff; //人员 int newcount=0; //新的索引项个数 for(int pos=0;posread(file); //读文件 pstaff->write (outfile); //写文件 delete pstaff; //删除存储空间 indextable[newcount++]=indextable[pos]; //复制索引项 } } count=newcount; // 新的索引项个数

file.close() ; //关闭文件 outfile.close(); //关闭文件 remove("staff.dat"); //移除文件 rename("tem.dat","staff.dat"); //重命名文件 file.open("staff.dat",ios::in|ios::out|ios::binary); //重新打开文件 cout

cout

char answer; //临时变量

cin>>answer; //接受输入

if(answer=='q')

{

system("cls"); //使用清屏函数 }

}

void login(int& loginsuccess); //登录系统函数

void main()

{ staffmanage objstaff; //建立员工管理对象

int loginsuccess = false; //设置登录标志

login (loginsuccess); //调用登录函数

if ( loginsuccess )

{ cout

objstaff .run (); //进入主菜单

}

else

{ system

//清屏

cout

}

("cls");

《高级语言程序设计》作业报告

作业名称: 公司员工管理系统

学 院 专 业 学生姓名 任课教师

提交日期 2014年6月27日

一、 问题描述

一间公司有各种人员,对人员信息的管理显得比较重要。于是,本系统是要

解决公司员工信息的管理。主要有信息的增加,查询,删除,更新等操作。解决了人员的增加,减少,变更等的情况。 二、

系统设计

1、类体系设计:

设计一个员工虚基类staff ,包含编号、姓名和年龄保护数据成员,还有相关的函数。因为公司里面人员的分类众多,难以找到统一标准,在此进行简化,暂且将人员分为管理方面和研究方面。所以,从基类中派生出研究人员类engineer, 里面增加专业,职称两个保护数据成员。同样地,管理类leader 也从基类派生,里面增加职位,部门两个保护数据成员。考虑到有的员工同时具有这两个性质,即同时兼有管理和研究的职责,于是从研究类和管理类中派生出研究管理类chairman ,该类属于多继承了前面的两个类。现在已经有四个类,而且它们具有继承关系。接着要考虑对数据的操作和对各种员工的管理操作,另外定义一个员工管理类staffmanage ,将各种操作函数,数据成员进行封装。至于各个类的成员函数都有自己的版本,利用多态性,用基类指针指向派生类对象进行调用。 2、数据结构分析

因为涉及到信息的处理,所以采用二进制文件staff.dat 保存数据。上述的类体系中,不同类层次的对象具有的数据成员不同,为了方便存储在一个二进制文件中并且能进行查询等操作,另外建立索引结构indextype ,并将索引存储在索引文件index.dat 中。索引结构中必须包含一个数据成员position 记录不同对象数据在二进制文件的相对存储位置。另外,查找数据的标志设置为人员的编号num ,为了便于进行删除操作,设删除标记deltag.

最后,文件操作时要确定写入的文件大小,需要有人员类型标记stafftypeb 便于分配存储空间。 3、类定义及成员函数功能描述:

虚基类staff :

class staff {

public:

staff(){} //构造函数 virtual~staff(){} //虚析构函数 const char*getnum()const{return num;} //返回编号 virtual void input()=0; //输入函数 virtual void show()const=0; //显示数据 virtual void read(fstream &f)const=0; //读文件 virtual void write(fstream &f)const=0; //写文件 protected:

char num[8]; //编号 char name[12];//姓名 int age; //年龄 }

该基类把员工的基本数据成员和基本操作都包含进来了。除了返回编号的函数有具体实现,其他函数都声明为纯虚函数。 研究人员类engineer

class engineer:virtual public staff {

public:

engineer(){} //构造函数 virtual~ engineer(){} //虚析构函数 void input(); //输入数据 void show()const; //显示数据 void read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(engineer)); };

void write(fstream &f)const //写文件 {

f.write((char*)this,sizeof(engineer)); };

protected:

char major[12]; //专业 char prof[12]; //职称 };

该类增加两个成员以记录更多的性质,函数也会给出具体实现,这里部分函数只做了声明。 管理人员类leader:

class leader:virtual public staff {

public:

leader(){}//构造函数

virtual~leader(){}//虚析构函数 void input();//输入数据

void show()const // 显示数据 { //显示信息

coutvoid read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(leader)); };

void write(fstream &f)const {

f.write((char*)this,sizeof(leader)); };

protected: //数据成员 char job[12]; //职务 char dep[12]; //部门 }

同样,管理人员类也声明了函数并给出了实现,增加了职务和部门两个数据成员。

管理及研究人员类chairman :

class chairman:public engineer,public leader {

public:

chairman(){} //构造函数 virtual~chairman(){} //虚析构函数 void input(); //输入数据 void show()const // 显示数据 void read(fstream &f)const //读文件 {

f.read((char*)this,sizeof(chairman)); };

void write(fstream &f)const //写文件 {

f.write((char*)this,sizeof(chairman)); };

该类继承了engineer 类和leader, 包含前两者的数据成员并且有自己版本的函数实现。

员工管理类manage: class staffmanage {public:

staffmanage(); //构造函数 virtual~staffmanage(); //虚析构函数 void run(); //菜单函数 private: //私有成员 fstream file; //人员数据文件 indextype*indextable ; //索引表

int maxsize; //最大索引项个数 int count; //索引项个数

void addindexitem(const indextype &e); //在索引表中增加索引项 void adddata(); //增加数据 void updatedata(); //更新数据 void searchdata(); //查询数据

void deledata(); //删除数据,只作删除标记 void pack(); //在物理上删除作有删除标记的纪录

};

该类统一了对数据文件的操作。数据成员有数据文件,索引表定义为动态的,还有索引项个数的记录和一个最大索引项限制。

4、程序流程图:

三、程序测试

1、 登录模块

密码正确即可,初始密码为zxw, 有3次输入机会 2、 初始界面

菜单简单,操作方便 3、 增加数据

在测试时输入三组不同数据,操作均有提示,最后按‘q’返回主界面。

4、 查询操作

按照编号查找,找到后输出数据。 5、 删除操作:

按照编号查找,显示成功删除的操作。 6、 修改数据:

按编号查找,之后进行修改,人员类型是否改变会有不同的操作。 7、 重组数据:

为了充分利用存储空间,在数据文件中的作有删除标记的数据要被删除。 8、 退出:选择‘6’即可退出。 四、使用说明

本系统操作很简单,按照它的说明进行操作就行。先要输入密码才能登录系统。菜单的前五个功能可以反复执行。 五、程序的改进及bug:

本程序相对比较简单,很多功能都很粗糙。比如不可以修改密码,比如不可以输入其他的数据。还有,对员工分类过于简单。这些确实可以逐渐完善,鉴于系统的完成时间有限,就没有优化。调试过程中发现一个BUG ,再次打开程序查找先前输入的数据时会出现异常,异常信息如下:

问题签名:

问题事件名称: APPCRASH 应用程序名:

公司员工管理系统.exe

应用程序版本: 0.0.0.0 应用程序时间戳:

53a6719d

故障模块名称: 公司员工管理系统.exe 故障模块版本:

0.0.0.0

故障模块时间戳: 53a6719d

异常代码: c0000005 异常偏移: 0001e72d

OS 版本: 6.1.7601.2.1.0.256.1 区域设置 ID: 其他信息 1: 其他信息 2: 其他信息 3: 其他信息 4:

2052 0a9e

0a9e372d3b4ad19135b953a78882e789 0a9e

0a9e372d3b4ad19135b953a78882e789

于是我一直查找异常的原因,估计是第二次运行的时候,初始化文件时,文件数据读入文件流时的绝对位置发生了改变。尝试修改程序,但是遗憾的是直至撰写报告的时候,我还是没有解决到问题。从这个过程中我深刻地感受到自己所懂得的实在是太少了。有一个BUG 实在很遗憾。其中也有自己写程序是大局观不够,没有全盘考虑有关。 六、收获与体会

1、这次的课程设计真的充分暴露了我的不足,很多东西都要不断查资料,而且平时编程没有养成好的习惯,编写速度比较慢。还有,收获也是比较大的,特别是对于文件处理这一方面,具体的定位,读写等都有了进一步的了解。对于类体系的设计,也要求考虑很多东西,锻炼了将问题解决的能力。

2、积累了经验,懂得了要编写较大的程序时要先有一个大体的想法框架,然后逐步完成,有点像逐步求精法一样。只要大的框架没有错,后面即使有错误都只是局部的错误,容易改正。

3、锻炼了耐心,有时候小错误要找很久。甚至找几天都找不到,确实很需要静下心来

慢慢找。

4、认识到自己的不足,很多都是要查阅资料,甚至有一个BUG 没法解决,导致本系统未能完成。虽然未能解决,但是寻求解决办法的过程中也学到很多东西,特别是对tellg()、seekg()这两个函数的了解,还有一些别人的经验。

附:完整程序

// C++大作业.cpp : 定义控制台应用程序的入口点。

//

#include

#include

#include

#include

#include

#define increament 1000 //增量

using namespace std;

//员工类

class staff

{

public:

staff(){} //构造函数

virtual~staff(){} //虚析构函数

const char*getnum()const{return num;} //返回编号

virtual void input()=0; //输入函数

virtual void show()const=0; //显示数据

virtual void read(fstream &f)const=0; //读文件

virtual void write(fstream &f)const=0; //写文件

protected:

char num[8];

char name[12];

int age;

};

//研究人员类

class engineer:virtual public staff

{

public:

engineer(){} //构造函数

virtual~ engineer(){} //虚析构函数

void input() //输入数据

{ //输入相关信息

cout

cin>>num;

} cout>name; cout>age; cout>major; cout>prof; void show()const // 显示数据 { //显示信息 coutvoid read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(engineer));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(engineer));

};

protected:

char major[12];

char prof[12];

};

//管理人员类

class leader:virtual public staff

{

public:

leader(){}//构造函数

virtual~leader(){}//析构函数

void input()

{ //输入相关信息

cout

cin>>num;

cout

cin>>name;

cout

cin>>age;

cout

cin>>dep;

cout

cin>>job;}

void show()const // 显示数据

{ //显示信息

cout

};

void read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(leader));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(leader));

};

protected: //数据成员

char job[12]; //职务

char dep[12]; //部门

};

//管理及研究人员类

class chairman:public engineer,public leader

{

public:

chairman(){} //构造函数

virtual~chairman(){} //虚析构函数

void input()

{ //输入相关信息

cout

cin>>num;

cout>name; cout>age; cout>dep; cout>job;

cout

cin>>major;

cout

cin>>prof;

}

void show()const // 显示数据

{ //显示信息

cout

};

void read(fstream &f)const //读文件

{

f.read((char*)this,sizeof(chairman));

};

void write(fstream &f)const

{

f.write((char*)this,sizeof(chairman));

};

};

//索引结构

struct indextype

{

bool deltag; //删除标记

char num[8]; //编号

int position; //在数据文件中的相对位置

char stafftype; //人员类型

};

class staffmanage

{public:

staffmanage() //构造函数

{

ifstream indexfile("idx.dat",ios::binary); //建立输入索引文件

if(!indexfile.fail())

{ //打开文件成功

indexfile.seekg(0,ios::end); //定位

count=indexfile.tellg()/sizeof(indextype); //索引项个数

maxsize=count+increament ; //索引表最大索引项个数

indextable=new indextype[maxsize]; //为索引表分配储存空间 indexfile.seekg(0,ios::beg); //定位

int i=0; //临时变量

indexfile.read((char*)&indextable[i++],sizeof(indextype));//读记录

while(!indexfile.eof()) //文件未结束时

{

indexfile.read((char*)&indextable[i++],sizeof(indextype)); //读记录

}

indexfile.close(); //关闭文件

}

else //打开文件失败

{

count=0; //索引项个数

maxsize=count+increament; //索引表最大索引项个数

indextable=new indextype[maxsize]; //分配储存空间

}

ifstream ifile("staff.dat"); //建立输入文件

if(ifile.fail()) //打开文件失败,表示不存在文件

{

ofstream ofile("staff.dat"); //建立输出文件

if(ofile.fail()) throw("打开文件失败!"); //抛出异常

ofile.close(); //关闭文件

}

else

{

ifile.close(); //关闭文件

}

file.open("staff.dat",ios::in|ios::out|ios::binary); //以读写方式打开文件

if (file.fail()) throw("打开文件失败!"); //抛出异常

}

virtual~staffmanage() //虚析构函数

{

ofstream indexfile("idx.dat",ios::binary); //建立输出索引文件

for(int i=0;i

{

indexfile.write((char*)&indextable[i],sizeof(indextype)); //写文件

}

indexfile .close(); //关闭文件

file.close(); //关闭文件

}

void run(); //处理菜单

private: //私有成员

fstream file; //人员数据文件

indextype*indextable ; //索引表

int maxsize; //最大索引项个数

int count; //索引项个数

void addindexitem(const indextype &e); //在索引表中增加索引项

void adddata(); //增加数据

void updatedata(); //更新数据

void searchdata(); //查询数据

void deledata(); //删除数据,只作删除标记

void pack(); //在物理上删除作有删除标记的纪录

};

void staffmanage::adddata() //增加数据

{

staff*pstaff; //人员

indextype item; //索引项

item.deltag=false; //删除标记

file.seekg(0,ios::end); //定位

char answer; //临时变量

do

{

do

{

cout

cin>>item.stafftype; //输入人员类型

item.stafftype=tolower(item.stafftype);

转换为小写字母

}while(item.stafftype!='e'&&item.stafftype!='l'&&item.stafftype!='c');

if(item.stafftype=='e')

pstaff=new engineer; //分配存储空间

else if(item.stafftype =='l')

pstaff=new leader; //分配存储空间

else pstaff=new chairman; //分配存储空间

pstaff->input(); //输入数据

strcpy_s(item.num,pstaff->getnum()); //复制编号

item.position=file.tellg(); //写入数据文件的位置

addindexitem (item); //在索引表增加索引项

pstaff->write(file); //写文件

delete pstaff; //释放存储空间

cout

cin>>answer; //输入选择

}

while(answer=='y');

cout

cout

char answer1;

cin>>answer1;

if(answer1=='q')

{

system("cls");

}

}

void staffmanage::addindexitem(const indextype &e) //在索引表中增加索引项

{

if(count>=maxsize) //索引表溢出

{

maxsize=maxsize+increament; //增加索引表容量

indextype*tmpindextable=new indextype[maxsize];//临时索引表

for(int i=1;i

} { tmpindextable[i]=indextable[i]; } delete []indextable; //释放索引表的存储空间 indextable=tmpindextable; // 指向临时索引表 } indextable[count++]=e; //加入到索引表中

void staffmanage::deledata () //删除数据

{

staff*pstaff; //人员

indextype item; //索引项

item.deltag=false; //删除标记

char num[12]; //临时变量

cout

cin>>num; //输入编号

int pos; //临时变量

for(pos=0;pos

{

if(strcmp(num,indextable[pos].num)==0&&!indextable[pos].deltag) //查找索引项位置

break;

}

if(pos

{

file.seekg(indextable[pos].position,ios::beg); //定位 if(indextable[pos].stafftype=='e') pstaff=new engineer; //分配存储空间 else if(indextable[pos].stafftype=='l') pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->read(file); //读文件 coutshow(); //显示信息 indextable[pos].deltag=true; //置删除标记 delete pstaff; //释放存储空间 cout

char answer; //临时变量

cin>>answer; //接受输入

if(answer=='q')

{

system("cls"); //使用清屏函数

}

}

void login(int &loginsuccess) //登录函数

{

cout

cout

for (int i = 0; i

{

char code[10];

cout

cin>>code;

if (strcmp("zxw",code)==0) //判断密码是否正确

{

cout

loginsuccess=true; //给登录标志置值

break;

}

cout

}

void staffmanage::run() //数

{

int select; //码

do

{

cout

cout

cout

cout

cout

cout

cout

cout

选择操作函选择菜单号

} cin>>select; //输入选择 while(cin.get()!='\n'); switch(select) { case 1: } adddata (); //增加数据 break; updatedata(); //更新数据 break; searchdata (); //查询数据 break; deledata(); //删除数据 break; pack(); //在物理上删break; case 2: case 3: case 4: case 5: 除作有删除标记的纪录 while(select!=6); //选择6时退出

}

oid staffmanage::searchdata() //查询人员

{

staff*pstaff; //人员

char num[12]; //临时变量

cout

cin>>num; //输入编号

int pos; //人员编号

for(pos=0;pos

{

if(strcmp(num,indextable[pos].num)==0&&!indextable[pos].deltag)

break;

}

if(pos

{

file.seekg(indextable[pos].position,ios::beg); //定位

if(indextable[pos].stafftype=='e')

pstaff=new engineer; //分配存储空间

else if(indextable[pos].stafftype=='l')

pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->read(file); //读文件 pstaff->show(); //显示数据 delete pstaff; //删除存储空间 } else { cout>answer; //接受输入 if(answer=='q') {

system("cls"); //使用清屏函数 }

void staffmanage::updatedata () //更新数据

{

staff*pstaff; //人员 indextype item; //索引项 item.deltag=false; //删除标记 char num[12]; //临时变量 cout>num; //输入编号 int pos; //临时变量 for(pos=0;posread(file); //读文件 pstaff->show(); //显示数据 do

";

cout>item.stafftype; //输item.stafftype=tolower(item.stafftype); //转换 入人员类型

为小写字母

}while(item.stafftype!='e'&&item.stafftype!='l'&&item.stafftype!='c'); if(item.stafftype =='e') pstaff=new engineer; //分配存储空间 else if(item.stafftype =='l') pstaff=new leader; //分配存储空间 else pstaff=new chairman; //分配存储空间 pstaff->input(); //输入数据 if(item.stafftype==indextable[pos].stafftype ) { strcpy_s(indextable[pos].num,pstaff->getnum()); //复制编号 file.seekg(indextable[pos].position,ios::beg); //定位 } else { indextable[pos].deltag=true; //删除标记 strcpy_s(item.num,pstaff->getnum()); //复制编号 file.seekg(0,ios::end); //定位 item.position=file.tellg(); //写入文件的位置 addindexitem (item); //增加索引项 } pstaff->write (file); //写文件 delete pstaff; //删除存储空间 cout>answer; //接受输入 if(answer=='q') { system("cls"); //使用清屏函数 }

}

void staffmanage::pack() //重组文件 {

if(indextable[pos].stafftype=='e') pstaff=new engineer; //分配存储空间 else if(indextable[pos].stafftype=='l') ofstream ofile("tem.dat") ; //建立输出文件 ofile.close(); //关闭文件 fstream outfile("tem.dat",ios::app|ios::binary); //打开文件 staff*pstaff; //人员 int newcount=0; //新的索引项个数 for(int pos=0;posread(file); //读文件 pstaff->write (outfile); //写文件 delete pstaff; //删除存储空间 indextable[newcount++]=indextable[pos]; //复制索引项 } } count=newcount; // 新的索引项个数

file.close() ; //关闭文件 outfile.close(); //关闭文件 remove("staff.dat"); //移除文件 rename("tem.dat","staff.dat"); //重命名文件 file.open("staff.dat",ios::in|ios::out|ios::binary); //重新打开文件 cout

cout

char answer; //临时变量

cin>>answer; //接受输入

if(answer=='q')

{

system("cls"); //使用清屏函数 }

}

void login(int& loginsuccess); //登录系统函数

void main()

{ staffmanage objstaff; //建立员工管理对象

int loginsuccess = false; //设置登录标志

login (loginsuccess); //调用登录函数

if ( loginsuccess )

{ cout

objstaff .run (); //进入主菜单

}

else

{ system

//清屏

cout

}

("cls");


相关文章

  • 关于上市公司实施员工持股计划试点的指导意见
  • 关于上市公司实施员工持股计划 试点的指导意见 为了贯彻<中共中央关于全面深化改革若干重大问题的决定>中关于"允许混合所有制经济实行企业员工持股,形成资本所有者和劳动者利益共同体"的精神,落实<国务院关于 ...查看


  • 中国保监会关于保险机构开展员工持股计划有关事项的通知
  • 保监发[2015]56号 各保险集团(控股)公司.保险公司.保险资产管理公司: 为建立股东.保险机构和员工利益共享机制,完善保险机构公司治理结构,规范保险机构薪酬激励机制,促进保险机构长期稳健发展,提高风险防范能力,现将保险机构开展员工持股 ...查看


  • XX公司员工手册
  • 地产开发有限公司员 工 手 册房地产开发有限公司员工手册序 言每一位员工加入 xx 都是为了成就我们共同的事业添砖加瓦. 每一位员工在这里走过的每一步,我们都希望,踏实而坚定. 所以,我们写下这本手册,希望能够为每位员工做一个进入 xx 的 ...查看


  • 天源商贸公司考勤管理细则
  • 天源商贸公司管理制度 大 纲 1.为了加强公司规范化管理,完善项工作制度,促进公司发展壮大,提高经济效益,根据国家有关法律.法规及公司章程的规定,特制订本管理制度. 2.公司全体员工都必须遵守公司章程,遵守公司的规章制度和各项决定.纪律.对 ...查看


  • 住宿管理制度
  • 目 录 第一章 总则 第二章 宿舍管理组织 第三章 宿舍入住审批 第四章 宿舍入宿办理 第五章 员工入住申请条件 第六章 宿舍管理规定 第七章 住宿的解除 第八章 员工宿舍卫生标准 第九章 住宿员工奖惩条例 第十章 退宿办理 第十一章 附则 ...查看


  • 兴业公司员工非物质激励方案设计
  • 兴业公司员工非物质激励方案设计 兴业公司员工激励现状分析 (一) 兴业公司概况 天水兴业市场发展有限公司成立于2000年,位于天水市秦州区滨河西路, 注册资本300万元,以市场开发.建设.市场信息咨询服务和房地产经营为主业, 以投资管理农产 ...查看


  • 员工离职管理控制程序
  • 1 目的 为完善公司员工辞职.辞退.自动离职及员工退休的管理机制,规范员工离职手续办理的管理程序. 2 范围 适用于本公司员工辞职.辞退.自动离职及员工退休的管理. 3 定义 3.1 辞职:公司员工根据个人意愿或因劳动合同期满不愿意续签合同 ...查看


  • 员工持股计划财务处理
  • 篇一:持股计划涉及到激励成分的会计.税务处理(修改版) 持股计划涉及到激励成分的会计.税务处理 相关问题:如果上市公司出资进行回购,以市价回购股份,但是以低于市价的价格进行员工持股计划,那么关于这笔钱: 一.公司的会计处理如何?是作为利润分 ...查看


  • 公司人力资源状况诊断报告书
  • 公司人力资源状况诊断报告与优化方案 中山市XXXXXX 有限公司成立于2001年,注册资本一百二十万元,公司占地面积8000多平方米,固定资产1500多万,拥有员工300多人.公司是一家集设计.加工.制造为一体的专业塑胶模具生产企业,属于技 ...查看


  • 员工职业生涯规划管理制度
  • 员工职业生涯规划管理制度 第一章 总则 适用范围 本管理办法适用于千里马工程机械集团股份有限公司全体员工(以下简称千里马机械,不含总经理). 目的 充分.合理.有效地利用公司内部的人力资源,实现公司人力资源需求和员工个人职业生涯需求之间的平 ...查看


热门内容