文章目錄
- 職工管理系統
- 一、職工管理系統詳解
- 二、職工管理系統功能詳解
- 1.頭檔案與結構體定義
- 2.使用的函式宣告
- 3.主函式與選單函式的宣告
- 4.添加函式
- 5.洗掉函式
- 6.查詢所有,查找某一員工資訊
- 7.修改函式
- 8.排序函式
- 9.插入函式
- 10.檔案保存
- 11.檔案讀取
- 總結
職工管理系統
因為這是在學習了一段時間后才寫的程式,一些知識都是前面學過的,所以我有關前面所學只是沒有寫的特別詳細,只是把我在寫的程序中被提醒或者被檢查出來的錯誤寫了上去,
一、職工管理系統詳解
該系統基于結構體與鏈表創建,有鏈表基本的增刪查改,排序,查找,插入,檔案的創建,保存,讀取和一些小功能,
也同樣優缺點:插入指定位置,能夠插入到指定位置,但退不出回圈,創建的臨時指標并未釋放,可能指向該電腦未知記憶體,萌新慎重copy,不建議copy全部代碼,
有些代碼粘貼過來原有層次分類沒有粘貼上,
二、職工管理系統功能詳解
1.頭檔案與結構體定義
代碼如下(示例):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
typedef struct Worker{
int number;
char name[20];
char sex[2];
int year;
int month;
int day;
char degree[20];
struct Worker *next;
}WOR;
在結構體中定義數值域與指標域,數值域儲存員工資訊,指標域儲存要連接的結構體地址,
2.使用的函式宣告
代碼如下(示例):
void menu();//選單
void showall(WOR *head);//顯示所有員工資訊
void attend(WOR *head); //添加員工資訊
void print(WOR *head);//查找某一員工資訊
void save(WOR *head);//保存職工資訊(只有值,用于檔案讀取)
void save1(WOR *head);//保存職工資訊(有值對應的具體資訊,用于用戶查閱)
void delte(WOR *head);//洗掉職工資訊
void change(WOR *head);//改變職工資訊
void order(WOR *head);//對職工資訊排序
void read(WOR *head);//讀取職工資訊
void insert(WOR *head);//插入職工資訊
void save2(WOR *head);//保存職工資訊(排序后的檔案)
在呼叫函式中需要加個小程式:進入函式需要有直接退出功能,以便不進行任何修改便可以直接退出,
3.主函式與選單函式的宣告
代碼如下(示例):
在主函式中對頭指標申請空間,后面所有函式定義void型別傳入引數頭指標,參考頭指標時最好不要直接使用,定義一個指標為頭指標再進行使用,
如果鏈表為慷訓者檔案為空都要有一一對應錯誤提示
int main()
{
WOR *head;
head=(WOR*)malloc(sizeof(WOR));
head->next=NULL;
while(1){
menu();
char n[1000];
printf("請選擇");
scanf("%s",n);
int a=strlen(n);
if(a>=2)
{
printf("你輸入的什么東西,拉出去,糟蹋了\n");
system("pause");
continue;
}
switch(n[0])
{
case '1':
read(head);
system("pause");
showall(head);
system("pause");
break;
case '2':
attend(head);
save(head);
save1(head);
system("pause");
break;
case '3':
delte(head);
save(head);
save1(head);
system("pause");
break;
case '4':
change(head);
save(head);
save1(head);
system("pause");
break;
case '5':
read(head);
print(head);
system("pause");
break;
case '6':
system("cls");
order(head);
save2(head);
system("pause");
break;
case '7':
insert(head);
save(head);
save1(head);
system("pause");
break;
case '8':
printf("歡迎下次使用\n");
system("pause");
exit(1);
break;
default:printf("別瞎輸,只能輸1-8\n");system("pause");break;
}
}
return 0;
}
void menu()//制作選單
{
system("cls");//清屏
printf(" 請規范輸入操作,不要輸入亂七八糟的的東西 \n");
printf("**************************************************\n");
printf("-------------歡迎來到喵喵嗷的管理系統-------------\n");
printf(" 1-查看當前所有的職工資訊 \n");
printf(" 2-添加職工資訊 \n");
printf(" 3-洗掉職工資訊 \n");
printf(" 4-修改職工資訊 \n");
printf(" 5-查看某一員工資訊 \n");
printf(" 6-按職工號對職工排序 \n");
printf(" 7-插入職工資訊 \n");
printf(" 8-退出 \n");
return;
}
注:只能輸入具有該指令的數字,輸入其他具有相對應的報錯提示
亂打:
輸入不是1-8

輸入超過個位數

注:因為我定義的是指字符陣列輸入,并且輸入超過陣列第一位就自動報出亂打錯誤
4.添加函式
代碼如下(示例):
添加決議:在主函式中定義的頭指標進行呼叫,定義新的臨時指標用頭指標依次鏈接,這是頭插法
在添加函式中根據結構體中的定義,對職工號要有查重操作,性別不能有除男女外其他,出生年月天都應該有他的限定,不能不符合常理,學位也要有對應的真是學位限制,
我沒有對月份是30天還是31天的判斷,以及是否是閏年對應2月天數限制,有精力和能力的人可以加以限制,完善代碼,
void attend(WOR *head)//添加員工資訊
{
int flag,i,a;
char n[20];
WOR *p=head;
WOR *s;//臨時儲存職工資料
printf("輸入0退出,其他繼續\n");
scanf("%s",n);
if(n[0]=='0')
return;
else
{
printf("請選擇要添加職工資訊的個數");
scanf("%d",&i);
if(i<=0)
return;
else
while(i)
{
s=(WOR*)malloc(sizeof(WOR));
tp:printf("請輸入職工號");
scanf("%d",&s->number);
WOR *q=head->next;
while(q)
{
a=q->number;
if(s->number==a)
{
printf("該職工號已被使用,其選擇其他喜歡的職工號");
goto tp;
}
q=q->next;
}
printf("請輸入姓名:");
scanf("%s",s->name);
getchar();
printf("請輸入性別: w/m ");
while(1)
{
scanf("%s",s->sex);
if(strcmp("w",s->sex)==0)
break;
if(strcmp("m",s->sex)==0)
break;
if(strcmp("W",s->sex)==0)
break;
if(strcmp("M",s->sex)==0)
break;
printf("不要創造新物種,請按要求輸入");
}
printf("請輸入出生年份:");
while(1)
{
scanf("%d",&s->year);
if(s->year<0)
{
printf("年份不能為負,請重新輸入");
continue;
}
else if(s->year>=0&&s->year<1000)
{
printf("年份太小,請重新輸入");
}
else
break;
}
printf("請輸入出生月份:");
while(1)
{
scanf("%d",&s->month);
if(s->month<=0||s->month>12)
{
printf("不要創造新月份,請重新輸入");
continue;
}
else
break;
}
printf("請輸入出生天:");
while(1)
{
scanf("%d",&s->day);
if(s->day<=0||s->day>31)
{
printf("不要創造新天數,請重新輸入");
continue;
}
else
break;
}
printf("請輸入職工學位:\n");
printf("注意:學歷有專科,本科,研究生,博士\n");
while(1)
{
scanf("%s",s->degree);
if(strcmp(s->degree,"專科")!=0&&strcmp(s->degree,"本科")!=0&&strcmp(s->degree,"研究生")!=0&&strcmp(s->degree,"博士")!=0)
{
printf("請按要求重新輸入");
}
else
break;
}
printf("\n");
while(p->next)
p=p->next;
p->next=s;
p=s;
p->next=NULL;
i--;
}
printf("創建成功\n");
return ;
}
}
注:添加一次員工資訊還需要能夠完成下一次添加,
5.洗掉函式
洗掉一個職工資訊,讓它的前一個指標直接連接到它的下一個指標,該指標脫離鏈表,再釋放掉,
洗掉一個職工資訊需要加個小程式:確定是否真的洗掉不想洗掉可以直接退出,

代碼如下(示例):
void delte(WOR *head)//洗掉函式
{
WOR *q=head;
if(q->next==NULL)
{
printf("無員工資訊,可選擇添加員工資訊以便吃掉\n");
}
else
{
WOR *p=q->next;
char a[20];
showall(head);
printf("請輸入要吃掉職工的職工號");
int n;
scanf("%d",&n);
while(p){
if(n==p->number)
{
printf("職工號:%d\n",p->number);
printf("姓名:%s\n",p->name);
printf("性別:%s\n",p->sex);
printf("出生年份:%d\n",p->year);
printf("月份:%d\n",p->month);
printf("天:%d\n",p->day);
printf("學位:%s\n\n\n",p->degree);
printf("請選擇是否繼續修改,0吃掉,其他都不吃掉");
scanf("%s",a);
if(strcmp(a,"0")==0)
{
q->next=p->next;
free(p);
p=NULL;
printf("該員工資訊已被吃掉");
return;
}
else
return;
}
printf("該員工資訊已被吃掉");
q=p;
p=p->next;
}
}
}
6.查詢所有,查找某一員工資訊
查詢所有職工資訊:這是一個遍歷鏈表并列印的程序,定義一個臨時指標儲存資訊一一將資訊輸出出來,
查詢某一員工資訊:首先需要遍歷鏈表找到員工資訊,定義臨時指標儲存該員工資訊再輸出,
代碼如下(示例):
void showall(WOR *head)//查詢所有員工資訊
{
char n[20];
printf("輸入0退出,其他繼續\n");
scanf("%s",n);
if(n[0]=='0')
return;
else
{
WOR *p;
p=head->next;
if(p==NULL)
{
printf("無員工資訊,可選擇添加員工資訊以增大公司規模\n");
}
else
{
printf("員工資訊\n");
while(p)
{
printf("職工號:%d\n",p->number);
printf("姓名:%s\n",p->name);
printf("性別:%s\n",p->sex);
printf("出生年份:%d\n",p->year);
printf("月份:%d\n",p->month);
printf("天:%d\n",p->day);
printf("學位:%s\n\n\n",p->degree);
p=p->next;
}
}
}
return;
}
void printf(WOR *head)//查詢某一員工
{
char n[20];
printf("輸入0退出,其他繼續\n");
scanf("%s",n);
if(n[0]=='0')
return ;
else
{
WOR *q,*p;
q=head;
if(q->next==Null)
{
printf("無員工資訊,可選擇添加員工資訊以增大公司規模\n");
}
else
{
int n;
printf("請選擇 1.職工號查詢 2.姓名查詢");
scanf("%d",&n);
if(n==1)
{
printf("請輸入職工號");
int a;
scanf("%d",&a);
p=head->next;
while(p)
{
if(a==p->number)
{
printf("職工姓名:%s\n",p->name);
printf("職工性別:%s\n",p->sex);
printf("職工出生年:%d\n",p->year);
printf("職工出生月:%d\n",p->month);
printf("職工出生日:%d\n",p->day);
printf("職工學位:%s\n",p->degree);
}
else if(a!=p->number)
{
printf("無職工資訊,可選擇添加增大公司規模\n");
return;
}
p=p->next;
}
}
else if(n==2)
{
printf("請輸入姓名");
char b[20];
scanf("%s",b);
while(p)
{
if(strcmp(p->name,"b")==0)
{
printf("職工號:%d\n",p->number);
printf("職工性別:%s\n",p->sex);
printf("職工出生年:%d\n",p->year);
printf("職工出生月:%d\n",p->month);
printf("職工出生日:%d\n",p->day);
printf("職工學位:%s\n",p->degree);
return ;
}
else if(strcmp(b,p->name)!=0)
{
printf("無職工資訊,可選擇添加增大公司規模\n");
return;
}
p=p->next;
}
}
}
}
}
注:查詢某一員工資訊:建議多多添加幾個方式查詢,
7.修改函式
修改員工資訊只需要遍歷鏈表找到職工資訊,直接修改就行,
修改時要和添加相似有對各個資訊的限制建議將那些小個程式直接寫成函式,本代碼就過于麻煩一個一個打,代碼冗長,
代碼如下(示例):
void change(WOR *head)//改變函式
{
WOR *q;
q=head;
if(q->next==NULL)
{
printf("無員工資訊,可選擇添加員工資訊以增大公司規模\n");
}
showall(head);
int flag,a;
int j;
printf("請輸入要修改的職工號");
scanf("%d",&j);
a=0;
while(q!=NULL)
{
if(q->number==j)
{
printf("職工號:%d\n",q->number);
printf("姓名:%s\n",q->name);
printf("性別:%s\n",q->sex);
printf("出生年份:%d\n",q->year);
printf("月份:%d\n",q->month);
printf("天:%d\n",q->day);
printf("學位:%s\n\n\n",q->degree);
printf("請選擇修改職工資訊:1.名字\n2.性別\n3.出生年\n4.出生月\n5.出生日\n6.學位\n7.修改全部");
scanf("%d",&flag);
system("cls");
if(flag==1)
{
printf("請重新輸入職工姓名");
scanf("%s",q->name);
system("pause");
break;
}
else if(flag==2)
{
printf("請重新輸入員工性別");
while(1)
{
scanf("%s",q->sex);
if(strcmp("w",q->sex)==0)
break;
if(strcmp("m",q->sex)==0)
break;
if(strcmp("W",q->sex)==0)
break;
if(strcmp("M",q->sex)==0)
break;
printf("不要創造新物種,請按要求輸入");
system("pause");break;
}
}
else if(flag==3)
{
printf("請重新輸入員工出生年份");
while(1)
{
scanf("%d",&q->year);
if(q->year<0)
{
printf("年份不能為負,請重新輸入");
continue;
}
else if(q->year>=0&&q->year<1000)
{
printf("年份太小,請重新輸入");
}
else
{
system("pause");
break;
}
}
}
else if(flag==4)
{
printf("請重新輸入員工出生月份");
while(1)
{
scanf("%d",&q->month);
if(q->month<=0||q->month>12)
{
printf("不要創造新月份,請重新輸入");
continue;
}
else
{
system("pause");
break;
}
}
}
else if(flag==5)
{
printf("請重新輸入員工出生天數");
while(1)
{
scanf("%d",&q->day);
if(q->day<=0||q->day>31)
{
printf("不要創造新天數,請重新輸入");
continue;
}
else
{
system("pause");
break;
}
}
}
else if(flag==6)
{
printf("請重新輸入員工學位");
while(1)
{
scanf("%s",q->degree);
if(strcmp(q->degree,"專科")!=0&&strcmp(q->degree,"本科")!=0&&strcmp(q->degree,"研究生")!=0&&strcmp(q->degree,"博士")!=0)
{
printf("請按要求重新輸入");
}
else
system("pause");
break;
}
}
else if(flag==7)
{
printf("請輸入姓名:");
scanf("%s",q->name);
getchar();
printf("請輸入性別: w/m ");
while(1)
{
scanf("%s",q->sex);
if(strcmp("w",q->sex)==0)
break;
if(strcmp("m",q->sex)==0)
break;
if(strcmp("W",q->sex)==0)
break;
if(strcmp("M",q->sex)==0)
break;
printf("不要創造新物種,請按要求輸入");
}
printf("請輸入出生年份:");
while(1)
{
scanf("%d",&q->year);
if(q->year<0)
{
printf("年份不能為負,請重新輸入");
continue;
}
else if(q->year>=0&&q->year<1000)
{
printf("年份太小,請重新輸入");
}
else
break;
}
printf("請輸入出生月份:");
while(1)
{
scanf("%d",&q->month);
if(q->month<=0||q->month>12)
{
printf("不要創造新月份,請重新輸入");
continue;
}
else
break;
}
printf("請輸入出生天:");
while(1)
{
scanf("%d",&q->day);
if(q->day<=0||q->day>31)
{
printf("不要創造新天數,請重新輸入");
continue;
}
else
break;
}
printf("請輸入職工學位:\n");
printf("注意:學歷有專科,本科,研究生,博士\n");
while(1)
{
scanf("%s",q->degree);
if(strcmp(q->degree,"專科")!=0&&strcmp(q->degree,"本科")!=0&&strcmp(q->degree,"研究生")!=0&&strcmp(q->degree,"博士")!=0)
{
printf("請按要求重新輸入");
}
else
break;
}
}
else
{
printf("選擇錯誤,請重新選擇");
system("pause");continue;
}
a=1;
}
q=q->next;
}
if(a==0)
printf("該員工不存在\n");
return;
}
8.排序函式
排序的程序不建議改變鏈表,可以使用冒泡排序,只交換數值域,不換指標域,
排序函式要有他自己對應的檔案,
代碼如下(示例):
void order(WOR *head)//對職工進行排序
{
char n[20];
printf("輸入0退出,其他繼續\n");
scanf("%s",n);
if(n[0]=='0')
return;
else
{
if(head->next==NULL)
{
printf("無員工資訊,可選擇添加員工資訊以排序\n");
return;
}
WOR *p=head->next;
WOR *q;
q=p->next;
WOR *temp;
while(p!=NULL)
{
q=p->next;
while(q!=NULL)
{
if(p->number>q->number)
{
int number1;
char name1[20];
char sex1[2];
int year1;
int month1;
int day1;
char degree1[20];
number1=p->number;
p->number=q->number;
q->number=number1;
strcpy(name1,p->name);
strcpy(p->name,q->name);
strcpy(q->name,name1);
strcpy(sex1,p->sex);
strcpy(p->sex,q->sex);
strcpy(q->sex,sex1);
year1=p->year;
p->year=q->year;
q->year=year1;
day1=p->day;
p->day=q->day;
q->day=day1;
month1=p->month;
p-> month=q->month;
q->month=month1;
strcpy(degree1,p->degree);
strcpy(p->degree,q->degree);
strcpy(q->degree,degree1);
}
q=q->next;
}
p=p->next;
}
}
}
9.插入函式
注:插入函式自己驗證時,雖然能夠插入到指定位置,但無法退出回圈,使用者慎重,
定義一個臨時指標儲存要插入的員工資訊,再將該指標插入指定的位置,
儲存資訊與添加一樣也需要有一系列的判斷,所以還是建議將限制寫成函式
插入圖解:

代碼如下(示例):
void insert(WOR *head)
{
char n[20];
printf("輸入0退出,其他繼續\n");
scanf("%s",n);
if(n[0]=='0')
return;
else
{
int v;
WOR *p=head;
WOR *s=(WOR *)malloc(sizeof(WOR));
printf("請輸入插入職工資訊");
s=(WOR*)malloc(sizeof(WOR));
tp:printf("請輸入職工號");
scanf("%d",&s->number);
WOR *q=head->next;
while(q)
{
v=q->number;
if(s->number==v)
{
printf("該職工號已被使用,其選擇其他喜歡的職工號");
goto tp;
}
q=q->next;
}
printf("請輸入姓名:");
scanf("%s",s->name);
getchar();
printf("請輸入性別: w/m ");
while(1)
{
scanf("%s",s->sex);
if(strcmp("w",s->sex)==0)
break;
if(strcmp("m",s->sex)==0)
break;
if(strcmp("W",s->sex)==0)
break;
if(strcmp("M",s->sex)==0)
break;
printf("不要創造新物種,請按要求輸入");
}
printf("請輸入出生年份:");
while(1)
{
scanf("%d",&s->year);
if(s->year<0)
{
printf("年份不能為負,請重新輸入");
continue;
}
else if(s->year>=0&&s->year<1000)
{
printf("年份太小,請重新輸入");
}
else
break;
}
printf("請輸入出生月份:");
while(1)
{
scanf("%d",&s->month);
if(s->month<=0||s->month>12)
{
printf("不要創造新月份,請重新輸入");
continue;
}
else
break;
}
printf("請輸入出生天:");
while(1)
{
scanf("%d",&s->day);
if(s->day<=0||s->day>31)
{
printf("不要創造新天數,請重新輸入");
continue;
}
else
break;
}
printf("請輸入職工學位:\n");
printf("注意:學歷有專科,本科,研究生,博士\n");
while(1)
{
scanf("%s",s->degree);
if(strcmp(s->degree,"專科")!=0&&strcmp(s->degree,"本科")!=0&&strcmp(s->degree,"研究生")!=0&&strcmp(s->degree,"博士")!=0)
{
printf("請按要求重新輸入");
}
else
break;
}
printf("請輸入插入點位置");
int a,b;
int l=0;
scanf("%d",&a);
WOR *c;
WOR *d=head;
if(a<=0)
return ;
else
{
while(d)
{
b++;
if(a==b)
{
c==(WOR *)malloc(sizeof(WOR));
c->number=s->number;
strcpy(c->name,s->name);
strcpy(c->sex,s->sex);
c->year=s->year;
c->month=s->month;
c->day=s->day;
strcpy(c->degree,s->degree);
c->next=d->next;
d->next=c;
printf("添加成功");
l=1;
return;
}
d=d->next;
}
if(l==0)
printf("添加失敗");
}
}
}
10.檔案保存
檔案的保存需要定義檔案指標,以及檔案輸入,
保存時建議保存兩個檔案,一個用來儲存,以及檔案內容呼叫,一個用來瀏覽觀看,
排序函式的檔案保存與之相似,
代碼如下(示例):
void save(WOR* head)//保存檔案函式
{
WOR* p;
FILE* fp;
if((fp=fopen("yyzhk.txt","w"))==NULL)
{
printf("檔案打開失敗\n");
}
else
{
p=head->next;
while(p!=NULL)
{
fprintf(fp,"%d %s %s %d %d %d %s\n",p->number,p->name,p->sex,p->year,p->month,p->day,p->degree);
p=p->next;
}
}
fclose(fp);
}
void save1(WOR *head)//保存顯示函式
{
WOR* p;
FILE* fp;
if((fp=fopen("yyzhk1.txt","w"))==NULL)
{
printf("檔案打開失敗\n");
}
else
{
p=head->next;
while(p!=NULL)
{
fprintf(fp,"職工號:%d 姓名:%s 性別:%s 出生年:%d 出生月:%d 出生日:%d 學位:%s\n",p->number,p->name,p->sex,p->year,p->month,p->day,p->degree);
p=p->next;
}
}
fclose(fp);
}
11.檔案讀取
在保存檔案后,再次讀取的時候需要將內容讀到鏈表中,這時候需要寫一個讀取函式,
代碼如下(示例):
void read(WOR *head)//讀取函式
{
WOR* p ,*s;
FILE* fp;
if((fp=fopen("yyzhk.txt","r"))==NULL)
{
printf("檔案打開失敗\n");
return;
}
else{
printf("打開成功\n");
p=head;
while(!feof(fp))
{
s=(WOR*)malloc(sizeof(WOR));
fscanf(fp,"%d %s %s %d %d %d %s\n",&s->number,s->name,s->sex,&s->year,&s->month,&s->day,s->degree);
p->next=s;
p=s;
p->next=NULL;
}
}
printf("讀取成功");
fclose(fp);
}
總結
本系統以鏈表知識為主,把鏈表的增刪查改理解之后,會發現其他功能與之其實都差不多,
如何遍歷鏈表很重要,萌新把這些理解之后基本大作業就能夠敲出來,
第一次寫博客,自我感覺良好, 希望這篇文章能幫助需要的人,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/240854.html
標籤:其他
下一篇:C語言 動態鏈表
