一个小练习:编制职工档案管理程序


编制职工档案管理程序

https://wwr.lanzoui.com/iLuj8qmsh0d密码:8x31

实现功能

导入或创建档案和导出档案

  1. 有文件,命名导入文件
  2. 无文件,输入数据创建档案并储存备份文件
  3. 导出排版后的全部职工档案列表(包含档案信息归纳)

检查问题档案

搜索显示信息

  1. 通过搜索姓名显示信息
  2. 通过搜索职工号显示信息

修改和删除部分数据

按类别显示全档案信息

快速排序

1、快速排序的基本思想:

快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

2、快速排序的三个步骤:

(1)选择基准:在待排序列中,按照某种方式挑出一个元素,作为 “基准”(pivot)

(2)分割操作:以该基准在序列中的实际位置,把序列分成两个子序列。此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大

(3)递归地对两个序列进行快速排序,直到序列为空或者只有一个元素。

发现&心得

1.处理较大数据时,尽量合并相关函数,减少调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(1)
{
t=p->next;
if(t==NULL)break;
else if(p->data.num==t->data.num)
{
t=Delete(p,t);
if(p->data.num==-1)n++;
else m++;
}
else
{
p=p->next;t=t->next;
}
}
1
2
3
4
5
6
staff Delete(staff head,staff node)
{
head->next=node->next;
free(node);
return node->next;
}

将Delete函数合并进check函数中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(1)
{
t=p->next;
if(t==NULL)break;
else if(p->data.num==t->data.num)
{
p->next=t->next;free(t);t=p->next;
if(p->data.num==-1)n++;
else m++;
}
else
{
p=p->next;t=t->next;
}
}

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>
typedef struct sta *staff;
#define SIZE sizeof(struct data)
#define N 100000 //最大数量
typedef struct data Data;
struct data
{
long num;//职工号
char name[20];//姓名
int sex; //性别,0为女性,1为男性
int part;//部门,以数字为代号
int age;//年龄
char addr[100];//地址
long sala;//基本工资
int edu;//文化程度,0博士、1硕士、2本科、3大专、4中专、5高中、6初中、7小学、8文盲、9半文盲
};
struct sta
{
Data data;
staff next;
};

int color(int num)
//num为每一种颜色所代表的数字,范围是0~15
{
//SetConsoleTextAttribute是设置控制台窗口字体颜色和背景色的函数
//GetStdHandle是获得输入、输出或错误的屏幕缓冲区的句柄
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),num);
return 0;
}

void databackup(staff node)
{
FILE *fp;
fp=fopen("databackup.dat","ab");
fwrite(&(node->data),SIZE,1,fp);
fclose(fp);
}

int Import_File(staff head)
{
FILE *fp;staff t=head;int i=1;char w;int c=1;int tt=0;
printf("开始");
while(1)
{
printf("导入文件,请确保将原始数据文件命名为""import.dat""复制到程序目录下后回车,输入N/n退出:");
fflush(stdin);
w=getchar();
if(w=='n'||w=='N')return 0;
if((fp=fopen("import.dat","rb"))==NULL)
{
color(12);printf("文件打开失败\n");c=0;printf("重新");
}
else break;
}
while(1)
{
staff node=(staff)malloc(sizeof(struct sta));
if(!node) {color(12);printf("结点创建失败\n ");c=0;break;}
node->next=NULL;
node->data.num=-1;node->data.age=-1;node->data.edu=-1;node->data.num=-1;node->data.part=-1;node->data.sala=-1;node->data.sex=-1;
if(!fread(node,SIZE,1,fp) && !tt){color(12);printf("文件错误\n");free(node);c=0;break;}
if(feof(fp)){free(node);break;}
databackup(node);
t->next=node;
t=node;i++;
tt++;
}
fclose(fp);
if(c==0){color(12);printf("导入失败。\n");return 0;}
else {color(10);printf("导入完成。\n");return 1;}
}

void Export(staff head)
{
FILE *fp,*fp1;
if(head==NULL){printf("档案为空,请载入档案后导出\n");return;}
if((fp1=fopen("data.dat","w"))==NULL){color(12);printf("导出失败。 ");return;}
if((fp=fopen("exportdata.txt","w"))==NULL){color(12);printf(" 导出失败。\n");return;}
staff temp=head;
//录入
while(temp)
{
fprintf(fp,"***********************************************************************************************************\n");
fprintf(fp,"职工号:\t%ld\n姓名:\t%s\n",temp->data.num,temp->data.name);
fprintf(fp,"性别:\t");
switch(temp->data.sex)
{
case 0:fprintf(fp,"女性\n");break;
case 1:fprintf(fp,"男性\n");
}
fprintf(fp,"部门:\t%d\n年龄:\t%d\n地址:\t%s\n基本工资:%ld\n",temp->data.part,temp->data.age,temp->data.addr,temp->data.sala);
fprintf(fp,"文化程度:");
switch(temp->data.edu)
{
//0博士、1硕士、2本科、3大专、4中专、5高中及以下
case 0:fprintf(fp,"博士");break;
case 1:fprintf(fp,"硕士");break;
case 2:fprintf(fp,"本科");break;
case 3:fprintf(fp,"大专");break;
case 4:fprintf(fp,"中专");break;
case 5:fprintf(fp,"高中");break;
case 6:fprintf(fp,"初中");break;
case 7:fprintf(fp,"小学");break;
case 8:fprintf(fp,"文盲");break;
case 9:fprintf(fp,"半文盲");
}
fprintf(fp,"\n");
fwrite(&(temp->data),SIZE,1,fp1);
temp=temp->next;
}
fclose(fp);
fclose(fp1);
printf("\n可读档案已导出至文件""exportdata.txt"",原始数据已导出至文件""data.dat""。请在程序目录下查看。\n");
color(15);printf("按任意键继续...\n");fflush(stdin);getchar();
return ;
}

int Input_List(staff head)
{

char x;staff t=head;int n=0;
printf("开始录入职工信息,\n原始数据会自动导出至文件databackup.dat,关闭程序后请在本程序所在目录查看。\n规则:\n1.按职工号,姓名,性别,部门,地址,基本工资,文化程度顺序逐个输入后回车\n2.性别输入数字,0代表女性,1代表男性\n3.文化程度输入数字:0博士、1硕士、2本科、3大专、4中专、5高中及以下\n");
while(1)
{
color(15);
printf("录入已经开始,请输入每一个数据后回车:\n");
staff node=(staff)malloc(sizeof(struct sta));
if(!node|| n==1) {color(12);printf("\n录入失败\n ");return 0;}
node->next=NULL;
node->data.num=-1;
//shuru//
printf("职工号:\t ");
scanf("%ld",&node->data.num);
printf("姓名:\t ");
scanf("%s",node->data.name);
printf("(输入数字,0代表女性,1代表男性)");printf("\n性别:\t ");
scanf("%d",&node->data.sex);
printf("部门:\t ");
scanf("%d",&node->data.part);
printf("年龄:\t ");
scanf("%d",&node->data.age);
printf("地址:\t "); fflush(stdin);
gets(node->data.addr);
printf("基本工资:");
scanf("%ld",&node->data.sala);
printf("(输入数字:0博士、1硕士、2本科、3大专、4中专、5高中及以下)");printf("\n文化程度:");
scanf("%d",&node->data.edu);
color(14);
printf("\n****************************************************\n请确认数据是否输入正确,输入C/c后回车撤销本次录入并重新输入,输入N/n后回车保存并退出录入,输入D/d删除本次输入并退出,输入其他键继续:\n");
fflush(stdin);
scanf("%c",&x);
color(10);
if(x=='C' || x=='c'){printf("已撤销。\n");free(node);}
else{
if(x=='D' || x=='d'){color(10);printf("\n删除成功,已退出录入。\n");free(node);break;}
databackup(node);
t->next=node;
t=node;
if(x=='N' || x=='n') {printf("\n已退出录入。原始数据将在程序退出后导出至文件databackup.dat\n");break;}
}
}
return 1 ;
}

staff FindListFoot(staff pHead){
staff pNode = pHead;
while(pNode->next != NULL){
pNode = pNode->next;
}

return pNode;
}

void swap(Data* a, Data* b){
Data t = *a;
*a = *b;
*b = t;
}

void Partition(staff pBegin, staff pEnd){
if(pBegin == NULL || pEnd == NULL || pBegin == pEnd)
return;
//定义两个指针
staff p1 = pBegin;
staff p2 = pBegin->next;
int pivot = pBegin->data.num;

while(p2 != NULL && p2 != pEnd->next){
if(p2->data.num < pivot){
p1 = p1->next;
if(p1 != p2){
swap(&p1->data, &p2->data);
}
}
p2 = p2->next;
}
swap(&p1->data, &pBegin->data);
//此时p1是中值节点

if(p1->data.num> pBegin->data.num)
Partition(pBegin, p1);
if(p1->data.num < pEnd->data.num)
Partition(p1->next, pEnd);
}

void QuickSort(staff pHead){
if(pHead==NULL)return;
staff pFoot = FindListFoot(pHead);
Partition(pHead, pFoot);
}

void Modify(staff node)
{ char x;int i;
while(1)
{
color(15);
printf("正在修改职工号为%ld的信息\n请输入序号选择修改内容:\n(1)姓名\t(2)性别\t(3)部门\t(4)年龄\t(5)地址\t(6)基本工资\t(7)文化程度\n",node->data.num);
fflush(stdin);
scanf("%d",&i);
switch(i)
{
case 1:printf("姓名:");
scanf("%s",node->data.name);break;
case 2:printf("性别(输入数字,0代表女性,1代表男性):");
scanf("%d",&node->data.sex);break;
case 3:printf("部门:");
scanf("%d",&node->data.part);break;
case 4:printf("年龄:");
scanf("%d",&node->data.age);break;
case 5:printf("地址:");
scanf("%s",node->data.addr);break;
case 6:printf("基本工资:");
scanf("%ld",&node->data.sala);break;
case 7:printf("文化程度(输入数字:0博士、1硕士、2本科、3大专、4中专、5高中及以下):");
scanf("%d",&node->data.edu);break;
}
color(15);
printf("****************************************************\n请确认数据是否输入正确,输入C/c后回车重新修改,输入N/n后回车保存并退出修改,输入D/d取消修改并退出,输入其他键继续:\n");
fflush(stdin);
scanf("%c",&x);
if(x=='C' || x=='c')printf("已撤销。\n");
else if(x=='D' || x=='d'){printf("\n已取消修改。\n");break;}
else if(x=='N' || x=='n') {printf("\n已退出修改。\n");break;}
}

}

void Check(staff head)
{
int n=0;
staff t,p;
p=head->next;
if(p!=NULL)
{
color(15);
printf("档案数据检查中...\n");
while(1)
{
t=p->next;
if(t==NULL)break;
else if(p->data.num==t->data.num || t->data.num<0 || t->data.num>N || t->data.age==-1 || t->data.edu==-1 || t->data.num==-1 || t->data.part==-1 || t->data.sala==-1 || t->data.sex==-1)
{
p->next=t->next;free(t);t=p->next;
n++;
}
else
{
p=p->next;t=t->next;
}
}
t=head->next;
if(t->data.num<0 || t->data.num>N || t->data.age==-1 || t->data.edu==-1 || t->data.num==-1 || t->data.part==-1 || t->data.sala==-1 || t->data.sex==-1)
{
p=head->next;
head->next=p->next;
free(p);
n++;
}

color(10);
if(n)printf("已删除%d个问题数据。\n",n);
else printf("数据正常。\n");
}
return ;
}

void Correct(staff head)
{ int z,n,i=0;staff t,p;
color(3);
printf("请选择功能:(1)修改\t(2)删除\n");
fflush(stdin);
scanf("%d",&z);
if(z==1)
{
printf("请输入要修改的职工号:");
fflush(stdin);
scanf("%d",&n);
staff t=head;
while(1)
{
if(t->data.num==n){Modify(t);break;}
t=t->next;
}
}
if(z==2)
{
printf("请输入要删除的职工号:");
fflush(stdin);
scanf("%d",&n);
p=head;t=p->next;
while(1)
{
if(t==NULL){color(12);printf("未找到该职工号信息。 ");break;}
if(t->data.num==n)
{
p->next=t->next;free(t);i=1;color(10);
printf("删除成功。\n");break;
}
else p=p->next;t=t->next;
}
}
}

void Search(staff head)
{
int n,i=0;staff t=head->next;color(15);
printf("请输入职工号搜索信息:");
fflush(stdin);
scanf("%d",&n);
while(1)
{
if(t->data.num==n)
{
printf("已找到:\n");
printf("姓名:\t %s\n",t->data.name);
printf("性别:\t ");
switch(t->data.sex)
{
case 0:printf("女性\n");break;
case 1:printf("男性\n");
}
printf("部门:\t %d\n年龄:\t %d\n地址:\t %s\n基本工资:%ld\n",t->data.part,t->data.age,t->data.addr,t->data.sala);
printf("文化程度:");
switch(t->data.edu)
{
//0博士、1硕士、2本科、3大专、4中专、5高中及以下
case 0:printf("博士");break;
case 1:printf("硕士");break;
case 2:printf("本科");break;
case 3:printf("大专");break;
case 4:printf("中专");break;
case 5:printf("高中");break;
case 6:printf("初中");break;
case 7:printf("小学");break;
case 8:printf("文盲");break;
case 9:printf("半文盲");
}
printf("\n****************************************************\n");
printf("按任意键继续...");fflush(stdin);getchar();return;
}
else t=t->next;
if(t==NULL){color(12);printf(" \n未搜索到信息\n");color(15);printf("按任意键继续...");fflush(stdin);getchar();break;}
}
}
void Statitics(staff head)
{
int a=0,b=0,c=0,d=0,i=0,n=0,male=0,female=0,sex=0;//a:<35,b:36~45,c:46~55,d:>55
staff t=head;
while(t)
{
if(t->data.age<35)a++;
else if(t->data.age>=36&&t->data.age<=45)b++;
else if(t->data.age>=46&&t->data.age<=55)c++;
else if(t->data.age>55)d++;
if(t->data.sex==0)female++;
else male++;
t=t->next;n++;
}
sex=male+female;
color(14);
printf("共%d人\n",sex);
printf("年龄分布情况:\n");
printf("小于35岁:%d人,占%d%%\n",a,100*a/n);
printf("36至45岁:%d人,占%d%%\n",b,100*b/n);
printf("46至55岁:%d人,占%d%%\n",c,100*c/n);
printf("大于55岁:%d人,占%d%%\n",d,100*d/n);
printf("\n****************************************************\n");
printf("性别分布情况:\n");
printf("女性:%d人,占%d%%\n",female,100*female/sex);
printf("男性:%d人,占%d%%\n",male,100*male/sex);
printf("按任意键继续...");fflush(stdin);getchar();
}

void chearan(int n,staff head)
{
if(head->next==NULL)return;
if(n==1)
{
staff p=FindListFoot(head),m;
staff t=(staff)malloc(sizeof(struct sta));
p->next=t;
t->next=NULL;
t->data.num=2114514191;t->data.edu=0;
m=FindListFoot(head);
QuickSort(head->next);
p->next=NULL;free(t);
}
else
return;
}

int main()
{
int z,t=0;staff head=(staff)malloc(sizeof(struct sta));head->next=NULL;color(11);
printf("\n****************************************************************************************************************\n****************************************************************************************************************\n******************************************欢迎使用编制职工档案管理程序******************************************\n****************************************************************************************************************\n*************************************************版本:20210623**************************************************\n****************************************************************************************************************\n****************************************************************************************************************\n");

FILE *fp=fopen("databackup.dat","wb");
fclose(fp);
while(1)
{
if(head->next==NULL)printf("档案数据为空。 ");color(15);printf("\n****************************************************");printf("\n请输入相应序号选择功能:\n(0):退出程序\n(1):输入职工信息\n(2):导入职工信息\n");
if(head->next!=NULL)printf("(3):检查问题档案\n(4):修改和删除部分数据\n(5):搜索信息\n(6):按类别显示全档案信息\n(7):导出全部职工档案\n****************************************************\n");
fflush(stdin);
scanf("%d",&z);

switch(z)
{
case 1:chearan(Input_List(FindListFoot(head)),head);break;
case 2:chearan(Import_File(FindListFoot(head)),head);break;
case 0:return 0;
}
Check(head);
if(head->next!=NULL)
switch(z)
{
case 3:Check(head);break;
case 4:Correct(head);break;
case 5:Search(head);break;
case 6:Statitics(head->next);break;
case 7:Export(head->next);break;
}


}

}