资源描述
. .
XX医药学院
信息管理与信息系统专业
《C程序设计》课程设计报告
题目:
职工信息管理系统
班级:
学号:
XX:
成绩:
前言
在理论学习和基础实验的基础上,开发规模较大的程序,掌握应用计算机解决实际问题的基本方法,熟悉C程序开发的全过程。本任务是根据给定的数据和程序,应用单向链表处理一个小班学生的信息。通过整个程序开发的过程,提高综合应用C语言的能力、编程和调试能力,为学习软件专业课程创建较扎实的理论基础和实践基础。
一、系统功能和原始数据
1、系统功能
A. 建立学生信息表,录入10名学生的信息,并将结果保存在文件student1.txt中
B. 显示所有学生信息
C. 给定某学生的学号,删除该学生的信息
D. 添加一名学生的信息,将其插入到相应位置,使整个学生信息表按学号有序
E. 给定某学生的学号,修改该学生的信息
F. 按XX查询学生信息
G. 按入学成绩对学生的信息进行排序
H. 计算并显示学生入学平均成绩,显示入学成绩最高分和最低分的学生信息
I. 将最后的学生信息存入文件student2.txt中
说明:
1. 学生信息数据项:学号、XX、性别、年龄、院系、入学成绩
2. 录入学生信息时按学号由小到大的顺序录入
3. 系统功能使用结构数组和单向链表两种方法实现
工资管理系统功能模块图
开始
以可读写的方式打开一个数据文件
将此文件的内容读出,并存入一个新的结构体类型的数组中
调用menu()菜单函数
进入while(1)主循环
输入0~9中的一数值,选择相应操作
输入是否为0
判断键值,调用相应函数,完成相应功能
是否已对修改进行了存盘
调用save()函数,进行写数据文件操作
结束
2.原始数据
工号
XX
性别
部门
职位
工资
100
米砂
女
公管学院
学生
500
101
米砾
男
公管学院
学生
500
102
罗斯
女
公管学院
学生
500
103
X满
男
公管学院
学生
500
104
林磊
男
公管学院
学生
500
105
胡水
女
公管学院
学生
500
106
王源
女
公管学院
学生
500
107
李君
男
公管学院
学生
500
108
X清
女
公管学院
学生
500
109
万羽
女
公管学院
学生
500
3.数据结构
本程序定义了结构体emplyee,用于存放职工的基本信息和工资信息。
typedef struct employee /*标记为employee*/
{
char num[10];
char name[15];
char sex;
char
char
int gz;
}ZGGZ
其各字段的值的含义如下。
num[10]: 保存职工编号
name [15]:保存职工XX
sex:保存职工性别
:保存职工部门
:保存职工职称
gz :保存职工工资
二、程序设计
1、建立职工信息结构体
(1)函数原型、功能和形参说明
1)、printheader()
函数原型:void printheader()
printheader()函数用于在以表格形式显示记录时,打印输出表头信息。
2)、printdata()
函数原型:void printdata(ZGGZ pp)
printdata()函数用于以表格显示的方式,打印输出单个数组元素pp中的记录信息。
3)、Disp()
函数原型:void Disp(ZGGZ tp[],int n)
Disp()函数用于显示tp数组中存储的n条记录,内容为emplyee结构中定义的内容。
4)、numberinput()
函数原型:float numberinput(char *notice)
numberinput()函数用于输入数值型数据,notice用于保存printf()中输出的提示信息。该函数返回用户输入的浮点类型数据值。
5)、Stringinput()
函数原型:void Stringinput(char *t,int lens,char *notice)
Stringinput()函数用于输入字符串,并进行字符串长度验证(长度<lens),t用于保存输入的字符串,因为是以指针形式传递的,所以t相当于该函数的返回值。notice用于保存printf()中输出的信息。
6)、Locate()
函数原型:int Locate(ZGGZ tp[],int n,char findmess[],char nameornum[])
Locate()函数用于定位数组中符合要求的元素,并返回该数组元素的下标值。参数findmess[]保存要查找的具体内容,nameornum[]保存按什么字段在数组tp中查找。
7)、Add()
函数原型:int Add(ZGGZ tp[],int n)
Add()函数用于在数组tp中增加工资记录元素,并返回数组中的当前记录数。
8)、Qur()
函数原型:void Qur(ZGGZ tp[],int n)
Qur()函数用于在数组tp中按职工编号或XX查找满足条件的记录,并显示出来。
9)、Del()
函数原型:int Del(ZGGZ tp[],int n)
Del()函数用于先在数组tp中找到满足条件的记录,然后删除该记录。
10)、Modify()
函数原型:void Modify(ZGGZ tp[],int n)
Modify()函数用于在数组tp中修改记录元素。
11)、Insert()
函数原型:int Insert(ZGGZ tp[],int n)
Insert()函数用于在数组tp中插入记录,并返回数组中的当前记录数。
12)、Tongji()
函数原型:void Tongji(ZGGZ tp[],int n)
Tongji()函数用于在数组tp中完成记录的统计工作,统计该公司职工工资的整体分布情况。
13)、Sort()
函数原型:void Sort(ZGGZ tp[],int n)
Sort()函数用于在数组tp中完成利用冒泡排序算法实现数组的按实发工资字段的降序排序。
14)、save()
函数原型:void Save(ZGGZ tp[],int n)
Save()函数用于将保存职工工资的数组tp中的n个元素写入磁盘的数据文件中。
15)、主函数main()
Main()是整个工资管理系统控制部分
(2)、程序清单
#inclu#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct employee
{
char num[10];
char name[15];
char sex[5];
char department[30];
char function[32];
int wage;
};
int read_file(struct employee st[]);
void menu();
void write_file(struct employee st[]);
void add();
void select(); //查看职工所有信息
void name_query(); //按XX查询
void num_del(); //按工号删除
void tongji(); //统计
void sort(); //排序
void num_modify(); //按工号修改职工信息
void save(); //保存信息
void fh(); //返回主菜单
struct employee st[300]; //这个数组用来保存所有的职工信息 和文件里面的一致
int Number=0; //记录总的职工人数 也就是数组/文件里面的职工人数
void main()
{
int choose=0;
FILE *fp=NULL;
char yesorno;
if((fp=fopen("student1.txt","rb+"))==NULL)
{
printf("\n=========>提示:文件不存在,是否要创建一个?(y/n)\n");
scanf("%c",&yesorno); if(yesorno=='y'||yesorno=='Y')
{
//这里仅为了建立文件
fp=fopen("student1.txt","wb+");
fclose(fp); //关闭fp所指的文件,释放文件缓冲区
}
else
exit(0);
}
else
{
Number=read_file(st); //要是文件已经有数据 将数据初始化到数组中
}
system("cls");
while(true)
{
menu();
printf("\t\t====>请选择:");
scanf("%d",&choose);
system("cls");
switch(choose)
{
case 0:
exit(0); //退出
break;
case 1:
add();
fh();//增加职工信息
break;
case 2:
select();
fh();//查看职工信息
break;
case 3:
name_query();
fh();// 查找
break;
case 4: num_del();
fh();//删除
break;
case 5: tongji();
fh();//统计
break;
case 6: sort();
fh();//排序
break;
case 7:
num_modify();
fh();//修改后返回
break;
case 8:
save();
fh();//保存
break;
default:
break;
}
fflush(stdin);
getchar();
system("cls");
}
}
void save()
{
printf("\t=====程序在运行时已自动保存.....\n");
}
void fh()
{
printf("\t===>按Enter键返回主菜单\n");
}
void num_modify() //修改职工信息
{
FILE *fp=NULL;
char xh[60];
int i=0;
int changeIndex=0; //changeIndex 改变标记
int index=0;
printf("请输入要修改的职工编号:");
scanf("%s",xh);
for (i=0;i<Number;i++)
{
if (strcmp(xh,st[i].num)==0) //比较输入工号和数组中已有工号
{
changeIndex=i; //保存要修改的人的下标
break;
}
}
printf("\t工号\tXX\t性别\t部门\t职能\t工资\n");
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[changeIndex].num,st[changeIndex].name,st[changeIndex].sex,st[changeIndex].department,st[changeIndex].function,st[changeIndex].wage);
printf("请重新输入该职工信息");
printf("工号:");
scanf("%s",st[changeIndex].num);
printf("XX:");
scanf("%s",st[changeIndex].name);
printf("性别:");
scanf("%s",st[changeIndex].sex);
printf("部门:");
scanf("%s",st[changeIndex].department);
printf("职能:");
scanf("%s",st[changeIndex].function);
printf("工资:");
scanf("%d",&st[changeIndex].wage);
//信息修改后重新更新文件里面的数据 以保持数据一致性
fp=fopen("student1.txt","wb+");
for (i=0;i<Number;i++)
{
fwrite(&st[i],sizeof(struct student),1,fp); //把ptr所指向n*size个字节输入到fp所指向的文件中
}
fclose(fp);
printf("\t=======>修改成功\n");
}
void sort()//排序
{
struct student t;
int wantNUmber=0;
int i=0;
int j=0;
int k=0;
for(i=0;i<Number-1;i++)
{
k=i;
for(j=i+1;j<Number;j++)
{
if(st[j].wage>st[k].wage)
k=j;
}
if(k!=i)
{
t=st[i];
st[i]=st[k];
st[k]=t;
}
}
printf("你想输出前几名的成绩:");
scanf("%d",&wantNUmber);
if (wantNUmber>Number)
{
wantNUmber=Number;
}
printf("\t工号\tXX\t性别\t部门\t职能\t工资\n");
for(i=0;i<wantNUmber;i++)
{
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[i].num,st[i].name,st[i].sex,st[i].department,st[i].function,st[i].wage);
}
}
void tongji()//统计
{
int i,m,k,max,min;
double sum=0.0;
for(i=0;i<Number;i++)
{
sum+=st[i].wage;
}
printf("总工资为:%f\n",sum);
printf("平均工资为:%f\n",sum/Number);
i=0;m=0;max=0;
max=st[m].wage;
for(i=1;i<Number;i++)
{
if (st[i].wage>max)
m=i;
max=st[m].wage;
}
printf("最高工资为:%d\n",max);
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[m].num,st[m].name,st[m].sex,st[m].department,st[m].function,st[m].wage);
i=0;k=0;min=0;
min=st[0].wage;
for(i=1;i<Number;i++)
{
if (st[i].wage<min)
k=i;
min=st[k].wage;
}
printf("最底工资分:%d\n",min);
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[k].num,st[k].name,st[k].sex,st[k].department,st[k].function,st[k].wage);
}
void num_del()//按工号删除
{
FILE *fp=NULL;
char xh[60];
int i=0;
int j=0;
printf("请输入要删除的职工工号:");
scanf("%s",xh);
for(i=0;i<Number;i++)
{
if (strcmp(xh,st[i].num)==0) //如果查找到就删除
{
for (j=i;j<Number-1;j++)
{
st[j]=st[j+1];
}
Number--;
}
}
//将剩余数据写入文件 重新一写的方式打开文件 把以前的数据擦除了
fp=fopen("student1.dat","wb");
for (i=0;i<Number;i++)
{
fwrite(&st[i],sizeof(struct student),1,fp);
}
fclose(fp);
printf("删除成功;\n");
}
void name_query()//按XX查找
{
char name[20];
int i=0;
printf("请输入要查找职工XX:");
scanf("%s",name);
system("cls");
printf("\t工号\tXX\t性别\t部门\t职能\t工资\n");
for (i=0;i<Number;i++)
{
if (strcmp(name,st[i].name)==0)
{
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[i].num,st[i].name,st[i].sex,st[i].department,st[i].function,st[i].wage);
}
}
}
void select()//查看职工
{
int i=0;
printf("以下是全部职工信息\n");
printf("\t工号\tXX\t性别\t部门\t职能\t工资\n");
for(i=0;i<Number;i++)
{
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",st[i].num,st[i].name,st[i].sex,st[i].department,st[i].function,st[i].wage);
}
}
void add()//增加职工
{
int numberTemp=0;
int i=0;
struct student temp; //临时保存信息
printf("请输入要增加职工个数:");
scanf("%d",&numberTemp);
for(i=0;i<numberTemp;i++)
{
printf("输入第%d个职工信息\n",i+1);
printf("工号:");
scanf("%s",temp.num);
printf("XX:");
scanf("%s",temp.name);
printf("性别:");
scanf("%s",temp.sex);
printf("部门:");
scanf("%s",temp.department);
printf("职能:");
scanf("%s",temp.function);
printf("工资:");
scanf("%d",&temp.wage);
st[Number++]=temp; //将刚添加的写入到数组
write_file(&temp); //将刚添加的写入到文件
}
printf("添加成功\n");
}
void write_file(struct student *st)
{
FILE *fp=NULL;
fp=fopen("student1.txt","rb+");
fwrite(st,sizeof(struct student),1,fp);
fclose(fp);
}
int read_file(struct student st[])
{
FILE *fp=NULL;
int i=0;
fp=fopen("student1.txt","rb");
while(fread(&st[i],sizeof(struct student),1,fp))
i++;
fclose(fp);
return i;
}
void menu()
{
printf("\t***********************************************************************\n");
printf("\t* *\n");
printf("\t* 职工信息管理系统_结构体数组实现 *\n");
printf("\t* *\n");
printf("\t* [1] 增加职工信息 [2] 查看职工信息 *\n");
printf("\t* [3] 查找职工信息 [4] 删除职工信息 *\n");
printf("\t* [5] 平均工资,最高工资,最底工资 [6] 工资排列 *\n");
printf("\t* [7] 修改职工信息 [8] 保存数据 *\n");
printf("\t* [0] 退出系统 *\n");
printf("\t* *\n");
printf("\t***********************************************************************\n");
}
(3)、运行结果
}}}
(3
主界面
增加职工信息
查看职工信息
查找职工信息
删除职工信息
平均工资
修改职工信息
保存数据
2)建立职工信息单链表
(1)、函数原型、功能和形参说明
(2)、程序清单
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int saveflag=0; /*是否需要存盘的标志变量*/
struct employee
{
char name[15]; /* 职工XX */
char num[10];/* 职工工号 */
char xb[4]; /* 职工性别 */
char bm[10]; /* 部门 */
char zc[10]; /* 工号职称 */
float gz; /* 工资 */
int mingci;/* 名次*/
};
typedef struct node
{
struct employee data;
struct node *next;
}Node,*Link;
//Link l (注意是:字母l不是数字1)
void add(Link l);
void disp(Link l); //查看职工所有信息
void del(Link l); //删除功能
Node* Locate(Link l,char findmess[],char nameornum[]);
void Qur(Link l); //查询功能
void Tongji(Link l); //统计
void Sort(Link l); //排序
void Modify(Link l); //修改功能
void Save(Link l); //保存功能
void printe(Node *p); //本函数用于打印链表中某个节点的数据内容 */
//以下4个函数用于输出中文标题
void printstart();
void Wrong();
void Nofind();
void printc();
void menu()
{ printf("\t*****************************************************************\n");
printf("\t* *\n");
printf("\t* 职工信息管理系统_单链表实现 *\n");
printf("\t* *\n"); printf("\t* [1] 增加职工信息 [2] 删除职工信息 *\n");
printf("\t* [3] 查询职工信息 [4] 修改职工信息 *\n");
printf("\t* [5] 插入职工信息 [6] 统计职工信息 *\n");
printf("\t* [7] 排序 [8] 保存职工信息 *\n");
printf("\t* [9] 显示数据 [0] 退出系统 *\n");
printf("\t* *\n");
printf("\t*****************************************************************\n");
} //void menu菜单结束
void Disp(Link l) //显示单链表l中存储的职工记录,内容为employee结构中定义的内容
{
int count=0;
Node *p;
p=l->next; // l存储的是单链表中头结点的指针,该头结点没有存储职工学生信息,指针域指向的后继结点才有职工信息
if(!p) /*p==NULL,NUll在stdlib中定义为0*/
{
printf("\n=====>提示:没有职工记录可以显示!\n");
return;
}
printf("\t\t\t\t显示结果\n");
printstart(); //打印横线
printc(); //打印职工信息
printf("\n");
while(p) //逐条输出链表中存储的职工信息
{
printe(p);
p=p->next;
}
printstart();
printf("\n");
} //void Disp结束
void printstart()
{
printf("-----------------------------------------------------------------------\n");
}
void Wrong()
{
printf("\n=====>提示:输入错误!\n");
}
void Nofind()
{
printf("\n=====>提示:没有找到该职工!\n");
}
void printc() /* 本函数用于输出中文 */
{
printf(" 工号\t XX 性别 部门 职称 工资\n");
}
void printe(Node *p)/* 本函数用于打印链表中某个节点的数据内容 */
{
printf("%-12s%s\t%s\t%s\t%s\t%s\t %d\n",
p->data.num,p->data.name,p->data.xb,p->data.bm,p->data.zc,p->data.gz);
}
//Locate(l,findmess,"num");
/* 该函数用于定位连表中符合要求的结点,并返回该指针 */
Node* Locate(Link l,char findmess[],char nameornum[])
{
Node *r;
if(strcmp(nameornum,"num")==0) /* 按工号查询 */
{
r=l->next;
while(r!=NULL)
{
if(strcmp(r->data.num,findmess)==0) /*若找到findmess值的工号*/
return r;
r=r->next;
}
}
else if(strcmp(nameornum,"name")==0) /* 按XX查询 */
{
r=l->next;
while(r!=NULL)
{
if(strcmp(r->data.name,findmess)==0) /*若找到findmess值的职工XX*/
return r;
r=r->next;
}
}
return 0; /*若未找到,返回一个空指针*/
}
//add()函数中,无节点时,r指向list头,有节点时,r指向末尾节点
void Add(Link l) /* 增加职工 */
{
Node *p,*r,*s; /*实现添加操作的临时的结构体指针变量*/
char num[10];
int flag=0;
r=l;
s=l->next; //链表没有节点时,s=null;/链表有节点时,指向第一个职工节点
while(r->next!=NULL) //如果存在后继结点时,r指针后移一个
r=r->next; /*将指针移至于链表最末尾,准备添加记录*/
while(1)
{
printf("请你输入工号(以'0'返回上一级菜单:)");
scanf("%s",num);
if(strcmp(num,"0")==0) //输入'0',跳出while(1),即跳出add()函数
break;
s=l->next; //作用? 每次从第一个节点开始找,看num是否重复。
while(s) //工号重复时,返回主菜单
{
if(strcmp(s->data.num,num)==0)
{
printf("=====>提示:工号为'%s'的职工已经存在,若要修改请你选择'4 修改'!\n",num);
flag=1;
//break;
return ;
}
s=s->next;
} //while(s)
p=(Node *)malloc(sizeof(Node)); //生成没赋值的新节点 p
strcpy(p->data.num,num);
printf("请你输入XX:");
scanf("%s",p->data.name);
getchar();
printf("请你输入性别:");
scanf("%s",p->data.xb);
getchar();
printf("请你输入部门:");
scanf("%s",&p->data.bm);
getchar();
printf("请你输入职称:");
scanf("%s",&p->data.zc);
getchar();
printf("请你输工资:");
scanf("%d",&p->data.gz);
getchar();
/* 信息输入已经完成 */
p->next=NULL; /*表明这是链表的尾部结点*/
r->next=p; /*将新建的结点加入链表尾部中*/
r=p;
saveflag=1;
} //while(1)
} //void Add增加结束
void Del(Link l) /* 删除 */
{
int sel;
Node *p,*r; /*实现删除操作的临时的结构体指针变量*/
char findmess[20];
if(!l->next) //当list无后继结点时,提示和结束返回del()
{
printf("\n=====>提示:没有记录可以删除!\n");
return;
}
printf("\n=====>1按工号删除\n=====>2按XX删除\n");
scanf("%d",&sel);
if(sel==1) //按工号删除
{
printf("请你输入要删除的工号:");
scanf("%s",findmess);
p=Locate(l,findmess,"num");
if(p)
{
r=l;
while(r->next!=p)
r=r->next; //从第一个结点找起,直到发现r->next=p, 是待删除结点,跳出循环
r->next=p->next; //r r->next(p) p->next
free(p);
printf("\n=====>提示:该职工已经成功删除!\n");
saveflag=1;
}
else
Nofind(); //显示一句话
} //if(sel==1)
else if(sel==2) //按XX删除
{
printf("请你输入要删除的XX:");
展开阅读全文