一、程序要求
該程序是由C語言編寫的一個宿舍管理查詢軟件,其主要功能是實現(xiàn)對學(xué)生信息的增加、刪除、修改、查詢、排序、存儲、加載。其中查詢可以分別以姓名、學(xué)號、寢室號為關(guān)鍵字查詢學(xué)生信息。排序可以分別以學(xué)號和寢室號為關(guān)鍵字進(jìn)行從小到大的排序。方便舍管阿姨管理宿舍。
二、程序設(shè)計
2.1、總體設(shè)計:
①輸入的形式:根據(jù)用戶所選擇的功能,然后再依據(jù)程序相應(yīng)的提示進(jìn)行輸入:
選擇功能1(添加學(xué)生信息):按照從先到后的順序輸入學(xué)生姓名(30個字符以內(nèi)),學(xué)生學(xué)號(15個字符以內(nèi)),宿舍號碼(整數(shù),范圍在0~32767)。
選擇功能2(修改學(xué)生信息):按照從先到后的順序輸入要修改的學(xué)生姓名(30個字符以內(nèi)),修改后學(xué)生的姓名(30個字符以內(nèi)),修改后學(xué)生的學(xué)號(15個字符以內(nèi)),修改后學(xué)生的宿舍號(整數(shù),范圍在0~32767)。
選擇功能3(刪除學(xué)生信息):輸入要刪除的學(xué)生姓名(30個字符以內(nèi))。
選擇功能4(以姓名查詢學(xué)生信息):輸入要查找的學(xué)生的姓名(30個字符以內(nèi))。
選擇功能5(以學(xué)號查詢學(xué)生信息):輸入要查找的學(xué)生的學(xué)號(15個字符以內(nèi))。
選擇功能6(以寢室號查詢學(xué)生信息):輸入寢室號(整數(shù),范圍在0~32767)。
②輸出的形式:根據(jù)用戶所選擇的功能不同,會有不同的輸出:
選擇功能1(添加學(xué)生信息):根據(jù)程序的判斷會輸出添加成功或者添加失敗。
選擇功能2(修改學(xué)生信息):根據(jù)程序的判斷會輸出修改成功或者修改失敗。
選擇功能3(刪除學(xué)生信息):根據(jù)程序的判斷會輸出刪除成功或者刪除失敗。
選擇功能4(以姓名查詢學(xué)生信息):根據(jù)程序的判斷,如果查找成功,則會輸出相應(yīng)的學(xué)生信息,反之,則會輸出查找失敗。
選擇功能5(以學(xué)號查詢學(xué)生信息):根據(jù)程序的判斷,如果查找成功,則會輸出相應(yīng)的學(xué)生信息,反之,則會輸出查找失敗。
選擇功能6(以寢室號查詢學(xué)生信息):根據(jù)程序的判斷,如果查找成功,則會輸出相應(yīng)的學(xué)生信息,反之,則會輸出查找失敗。
選擇功能7,8(以寢室號和學(xué)號為關(guān)鍵字進(jìn)行從小到大的排序):程序會輸出排序成功。
選擇功能9(顯示所有學(xué)生的信息):程序會輸出所有以存學(xué)生的信息。
選擇功能10(保存操作):根據(jù)程序的判斷會輸出保存成功或者保存失敗。
選擇功能11(加載記錄):根據(jù)程序的判斷會輸出加載記錄成功或者加載記錄失敗。
2.2、詳細(xì)設(shè)計
2.本程序所包含的15個函數(shù)為:
(1).主函數(shù)main();
(2).菜單函數(shù)Menu();
(3).判斷學(xué)號是否重復(fù)函數(shù)S_number_Judge(Student S,int t);
(4).添加學(xué)生信息函數(shù)Add(Student S);
(5).修改學(xué)生信息函數(shù)Alter(Student S);
(6).刪除學(xué)生信息函數(shù)Delete(Student S);
(7).顯示所有學(xué)生信息函數(shù)Display_All(Student S);
(8).按照寢室號從小到大排序函數(shù)Sort_D_number(Student S);
(9).按照學(xué)號從小到大排序函數(shù)Sort_S_number(Student S);
(10).根據(jù)學(xué)生姓名查找函數(shù)Query_S_name(Student S);
(11).根據(jù)學(xué)生學(xué)號查找函數(shù)Query_S_number(Student S);
(12).根據(jù)寢室號查找函數(shù)Query_D_number(Student S)
(13).存儲函數(shù)Save(Student S);
(14).加載函數(shù)Load(Student S);
(15).判斷在退出程序時是否保存函數(shù)Judge_Save(int i,Student S);
各函數(shù)之間的調(diào)用關(guān)系如下:
三、系統(tǒng)實現(xiàn)
部分程序代碼:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 100
int dirty=0;? //用來判斷是否已保存操作
//定義一個存儲學(xué)生相關(guān)信息的結(jié)構(gòu)體
typedef struct
{
char S_name[31];?? //學(xué)生姓名
char S_class[31];? //學(xué)生班級
char S_number[16]; //學(xué)生學(xué)號
int D_number;????? //學(xué)生所在寢室的宿舍號
char S_address[500]; //學(xué)生地址
int S_phone[20];? //學(xué)生電話號碼
int Total;???????? //學(xué)生總數(shù)
}Student[M],St;
//判斷學(xué)號是否與表中所存學(xué)號重復(fù)
void S_number_Judge(Student S,int t)
{
int i;
for(i=1;i<=(S->Total)-1;i++)
while(strcmp(S[i].S_number,S[t].S_number)==0)
{
printf("學(xué)號輸入失敗,該學(xué)號已存在,請重新輸入學(xué)號!n");
printf("請輸入學(xué)生的學(xué)號(15個字符以內(nèi)):");
scanf("%s",S[t].S_number);
getchar();
i=1;
}
}
//添加學(xué)生信息函數(shù)
void Add(Student S)
{
printf("請輸入學(xué)生姓名(30個字符以內(nèi)):");
scanf("%s",S[++(S->Total)].S_name);
getchar();//獲取換行符
printf("請輸入學(xué)生班級(30個字符以內(nèi)):");
scanf("%s",S[S->Total].S_class);
getchar();
printf("請輸入學(xué)生的學(xué)號(15個字符以內(nèi)):");
scanf("%s",S[S->Total].S_number);
getchar();
S_number_Judge(S,S->Total);//判斷輸入的學(xué)號是否與表中所存在的學(xué)號重復(fù)
printf("請輸入宿舍號碼:");
scanf("%d",&S[S->Total].D_number);
getchar();
printf("請輸入學(xué)生地址:");
scanf("%s",S[S->Total].S_address);
getchar();
printf("請輸入學(xué)生電話號碼:");
scanf("%s",&S[S->Total]. S_phone);
getchar();
dirty=1;
printf("添加成功!nn");
}
//刪除學(xué)生信息
void Delete(Student S)
{
int i,j;
int flag=0;? //用來判斷表中是否存在所要刪除的學(xué)生的信息
char name[20];
printf("請輸入你要刪除學(xué)生的姓名:");
scanf("%s",name);
getchar();
for(i=1;i<=S->Total;i++)
if(strcmp(S[i].S_name,name)==0)
flag=i;
if(!flag)
printf("你所要刪除的學(xué)生在表中不存在!");
else
{
for(i=flag;i<S->Total;i++)
{
j=i+1;
strcpy(S[i].S_name,S[j].S_name);
strcpy(S[i].S_number,S[j].S_number);
S[i].D_number=S[j].D_number;
}
(S->Total)--;
dirty=1;
printf("刪除成功!");
}
printf("nn");
}
//排序函數(shù)按照寢室號從小到大排序(冒泡法)
void Sort_D_number(Student S)
{
int i,j,t;
char name[30];
char number[15];
char address[300];
char Cnumber[30];
for(i=1;i<=S->Total;i++)
for(j=i;j<=S->Total;j++)
if(S[i].D_number>S[j].D_number)
{
strcpy(name,S[i].S_name);
strcpy(number,S[i].S_number);
strcpy(address,S[i].S_address);
strcpy(Cnumber,S[i].S_class);
t=S[i].D_number;
strcpy(S[i].S_name,S[j].S_name);
strcpy(S[i].S_number,S[j].S_number);
strcpy(S[i].S_address,S[j].S_address);;
strcpy(S[i].S_class,S[j].S_class);
S[i].D_number=S[j].D_number;
strcpy(S[j].S_name,name);
strcpy(S[j].S_number,number);
strcpy(S[j].S_address,address);
strcpy(S[j].S_class,Cnumber);
S[j].D_number=t;
}
}
//排序函數(shù)按照學(xué)號從小到大排序(冒泡法)
//排序函數(shù)按照班級號從小到大排序(冒泡法)
void Sort_S_class (Student S)
{
int i,j,t;
char name[30];
char number[15];
char address[300];
char? Cnumber[30];
for(i=1;i<=S->Total;i++)
for(j=i;j<=S->Total;j++)
if(strcmp(S[i].S_class,S[j].S_class)>0)
{
strcpy(name,S[i].S_name);
strcpy(number,S[i].S_number);
strcpy(address,S[i].S_address);
strcpy(Cnumber,S[i].S_class);
t=S[i]. D_number;
strcpy(S[i].S_name,S[j].S_name);
strcpy(S[i].S_number,S[j].S_number);
strcpy(S[i].S_address,S[j].S_address);;
strcpy(S[i].S_class,S[j].S_class);
S[i]. D_number =S[j]. D_number;
strcpy(S[j].S_name,name);
strcpy(S[j].S_number,number);
strcpy(S[j].S_address,address);
strcpy(S[j].S_class,Cnumber);
S[j]. D_number =t;
}
}
//查詢函數(shù)以班級為關(guān)鍵字進(jìn)行查詢(順序查找)
void Query_S_class(Student S)
{
int i,j=0;
char classnumber[31];
printf("請輸入你要查找的班級號(30個字符以內(nèi)):");
scanf("%s",classnumber);
getchar();
printf("所查找學(xué)生信息如下:n");
printf("學(xué)生姓名???? 學(xué)生班級????? 學(xué)生學(xué)號????? 宿舍號????? 學(xué)生地址????? 學(xué)生電話號碼n");
for(i=1;i<=S->Total;i++)
if(strcmp(classnumber,S[i].S_class)==0)
{
printf("%-20s%-20s %-15s%-5d%s-10%sn",S[i].S_name, S[i].S_class,S[i].S_number,S[i].D_number,S[i].S_address,S[i].S_phone);
j=1;
}
if(!j)
printf("n查找失敗,表中不存在該學(xué)生的信息!nn");
}
//查詢函數(shù)以姓名為關(guān)鍵字進(jìn)行查詢(順序查找)
void Query_S_name(Student S)
{
int i,j=0;
char name[31];
printf("請輸入你要查找的學(xué)生的姓名(30個字符以內(nèi)):");
scanf("%s",name);
getchar();
printf("所查找學(xué)生信息如下:n");
printf("學(xué)生姓名???? 學(xué)生班級????? 學(xué)生學(xué)號????? 宿舍號????? 學(xué)生地址????? 學(xué)生電話號碼n");
for(i=1;i<=S->Total;i++)
if(strcmp(name,S[i].S_name)==0)
{
printf("%-20s%-20s %-15s%-5d%s-10%sn",S[i].S_name, S[i].S_class,S[i].S_number,S[i].D_number,S[i].S_address,S[i].S_phone);
j=1;
}
if(!j)
printf("n查找失敗,表中不存在該學(xué)生的信息!nn");
}
//查詢函數(shù)以學(xué)號為關(guān)鍵字進(jìn)行查詢(折半查找)
void Query_S_number(Student S)
{
int i,j,top,base,mid;
char number[15];
j=0;
base=1;
top=S->Total;
printf("請輸入你要查找學(xué)生的學(xué)號:");
scanf("%s",number);
getchar();
Sort_S_number(S);? //將表中原數(shù)據(jù)按照學(xué)號從小到大排序
printf("所查找學(xué)生信息如下:n");
printf("學(xué)生姓名???? 學(xué)生班級????? 學(xué)生學(xué)號????? 宿舍號????? 學(xué)生地址????? 學(xué)生電話號碼n");
if(strcmp(number,S[1].S_number)>=0&&strcmp(number,S[S->Total].S_number)<=0)
{
while(base<=top)
{
mid=(base+top)/2;
if(strcmp(number,S[mid].S_number)==0)
{
printf("%-20s%-20s%-15s%-5d%s-10%sn",S[i].S_name, S[i].S_class,S[i].S_number,S[i].D_number,S[i].S_address,S[i].S_phone);
putchar('n');
j=1;
break;
}
else if(strcmp(number,S[mid].S_number)>0)
base=mid+1;
else
top=mid-1;
}
}
if(!j)
printf("n查找失敗,表中不存在該學(xué)生的信息!nn");
}
//查詢函數(shù)以寢室號為關(guān)鍵字進(jìn)行查詢(折半查找)
void Query_D_number(Student S)
{
int i,j,m,n,base,top,mid;
j=0;
base=1;
top=S->Total;
printf("請輸入你要查詢的寢室號:");
scanf("%d",&i);
getchar();
Sort_D_number(S);//將表中原數(shù)據(jù)按照寢室號從小到大排序
printf("所查找寢室信息如下:n");
printf("學(xué)生姓名???? 學(xué)生班級????? 學(xué)生學(xué)號????? 宿舍號????? 學(xué)生地址????? 學(xué)生電話號碼n");
if(i>=S[1].D_number&&i<=S[S->Total].D_number)
{
while(base<=top)
{
mid=(base+top)/2;
if(i==S[mid].D_number)
{
m=mid;
n=mid-1;
while(S[m].D_number==i)
{
printf("%-20s%-20s %-15s%-5d%s-10%sn",S[m].S_name, S[i].S_class,S[m].S_number,S[m].D_number,S[i].S_address,S[i].S_phone);
m++;
if(m>S->Total)
break;
}
if(n>0)
{
while(S[n].D_number==i)
{
printf("%-20s%-15s%-5dn",S[n].S_name,S[n].S_number,S[n].D_number);
n--;
if(n<1)
break;
}
}
j=1;
putchar('n');
break;
}
else if(i>S[mid].D_number)
base=mid+1;??? //折半查找
else
top=mid-1;
}
}
if(!j)
printf("n查找失敗,表中不存在該寢室的信息!nn");
}
//存儲函數(shù)
void Save(Student S)
{
St Std;
int i;
int flag1=0,flag2=0; //判斷存儲是否成功
FILE *fp;
if((fp=fopen("宿舍管理.txt","w"))==NULL)
{
printf("打開文件失敗!nn");
flag1=1;
exit(0);? //結(jié)束程序
}
for(i=1;i<=S->Total;i++)
if(fwrite(&S[i],sizeof(Std),1,fp)!=1)
{
printf("數(shù)據(jù)寫入錯誤nn");
flag2=1;
exit(0);
}
if(!flag1&&!flag2)
{
printf("數(shù)據(jù)存儲成功!nn");
dirty=0;
}
fclose(fp);?? //關(guān)閉一個流。關(guān)閉一個打開的文件, fp是此前通過調(diào)用fopen返回的文件指針。
}
//加載記錄函數(shù)
void Load(Student S)
{
St Std;
FILE *fp;
if((fp=fopen("宿舍管理.txt","r"))==NULL)
{
printf("打開文件失敗!nn");
exit(0);
}
while(!feof(fp))?? // fp為文件句柄,feof為判斷是否讀到文件尾
fread(&S[++(S->Total)],sizeof(Std),1,fp);
fclose(fp);
printf("加載數(shù)據(jù)成功!nn");
(S->Total)--;?? //由于讀取問題,表中個數(shù)要減去
}
//退出程序時判斷是否保存函數(shù)
void Judge_Save(int i,Student S)
{
char ch;
if(i)
{
printf("表中數(shù)據(jù)已改變,是否保存后再退出(Y/N)?:");
ch=getchar();
getchar();
while(ch!='n'&&ch!='N'&&ch!='y'&&ch!='Y')
{
printf("請輸入N(n)或者Y(y):");
ch=getchar();
getchar();
}
if(ch=='y'||ch=='Y')
Save(S);
}
}
//菜單
void Menu()
{
//菜單
printf("?????????????????????????????????? 宿舍管理nn");
printf("*************************************菜單*************************************n");
printf("1.添加新入住學(xué)生信息???????????????? |?? 8.按照班級號從小到大排序n");
printf("2.修改宿舍學(xué)生信息?????????????????? |?? 9.按照寢室號從小到大排序n");
printf("3.刪除搬出宿舍學(xué)生信息?????????????? |?? 10.按照學(xué)號從小到大排序n");
printf("4.以姓名查詢學(xué)生信息???????????????? |?? 11.顯示所有學(xué)生的相關(guān)信息n");
printf("5.以學(xué)號查詢學(xué)生信息???????????????? |?? 12.保存操作n");
printf("6.以宿舍號查詢該宿舍中的全部學(xué)生信息 |?? 13.加載記錄n");
printf("7.以班級號查詢該班級中的全部學(xué)生信息 |?? 14.退出程序n");
printf("******************************************************************************n");
}
void main()
{
int i;
Student S;
S->Total=0;
do
{
Menu();
printf("請選擇所要實現(xiàn)的功能(請輸入1~14中的任意一個數(shù)字):");
scanf("%d",&i);
getchar();? //獲取換行符
putchar('n');
switch(i)
{
case 1:Add(S);
break;
case 2:Alter(S);
break;
case 3:Delete(S);
break;
case 4:Query_S_name(S);
break;
case 5:Query_S_number(S);
break;
case 6:Query_D_number(S);
break;
case 7: Query_S_class (S);
break;
case 8: Sort_S_class (S);
printf("排序完成!nn");
break;
case 9:Sort_D_number(S);
printf("排序完成!nn");
break;
case 10:Sort_S_number(S);
printf("排序完成!nn");
break;
case 11:Display_All(S);
break;
case 12:Save(S);
break;
case 13:Load(S);
break;
case 14:Judge_Save(dirty,S);
exit(0);
break;
default:printf("選擇錯誤:請在選項到之間選擇!nn");
break;
}
}while(i!=14);
}
四、系統(tǒng)調(diào)試
1、初次使用在菜單中選1輸入入住學(xué)生信息
按照先后順序分別輸入:
姓名:吳武,學(xué)號:20132255,班級:高三1班,宿舍號:404 ,地址27#,號碼13878797218
姓名:周王,學(xué)號:20132551,班級:高三1班,宿舍號:402,地址:27#,號碼 15296812933
姓名:秦學(xué),學(xué)號:20135599,班級:高三2班,宿舍號:403,地址:27#,號碼 15240662499
分別如下圖:
2、對功能2(修改學(xué)生信息)的測試:修改學(xué)生秦學(xué)的信息
如圖
3、對功能3(刪除學(xué)生信息)的測試:刪除搬出宿舍學(xué)生吳武的信息
如圖
4、對功能4(以姓名查詢學(xué)生信息)的測試:查詢學(xué)生秦學(xué)的信息
如圖
5、對功能6的測試:查詢宿舍402
6、對功能9進(jìn)行測試:
需要全部資料可在我的資源里下載,內(nèi)容包括程序文檔、源程序。
需要完整的資料可在我的資源里下載,也可以加入我的紛傳圈子,里面有資源壓縮包的百度網(wǎng)盤下載地址及提取碼。
紛傳點擊用微信打開即可,過程有點繁瑣請見諒。