課程設計————學生資訊管理系統(包含歷代思路和程式碼)
阿新 • • 發佈:2019-02-01
課程設計————學生管理系統(包含歷代思路和程式碼)
一.前言
學生資訊管理系統是我第一個獨立完成的比較長的程式碼,也算是花費了一些心血,這個系統是我一點點把它從幾百行的程式碼逐漸優化到上千行,功能從簡單到複雜。在這裡我把我的思路分享給大家,希望能給大家帶來一些幫助。
相比較上一篇部落格(學生管理系統)而言,這一篇,主要講的是我逐步優化的思路和過程。以及在那篇部落格後,繼續進行的優化。
二.學生管理系統1.0版
1. 實現功能
- 簡單的密碼驗證
- 學生資訊的錄入(連結串列的建立)
- 學生資訊的增.刪.改.查
- 按照平均分排序輸出
2. 函式框架
int main(void)
{
int a;
struct student *pHead;
show1();
while (1)
{
system("cls");//清屏
show2();//介面
fflush(stdin);
scanf("%d",&a);
switch(a)
{
case 1:pHead=input();break;//輸入
case 2:output(pHead);break;//輸出
case 3:increase(pHead);break;//增加
case 4:strike_out(pHead);break ;//刪除
case 5:chang(pHead);break;//修改
case 6:inquiry(pHead);break;//查詢
case 7:sore(pHead);break;//排序
case 0:exit(0);break;
default :printf("輸入有誤請重新輸入\n");break;
}
printf("按任意鍵進行下一步操作\n");
getch();
}
}
3. 函式呼叫關係圖
4. 部分功能函式
- 連結串列的建立輸出和增刪改查
這一部分大家可以參考我之前的部落格(連結串列及其簡單應用),裡面有較詳細的說明 - 連結串列的排序
這一部分在我之前的部落格(連結串列及其簡單應用)中也有寫到,裡面介紹了兩種排序,連結串列的氣泡排序和插入排序。相比較而言,其實插入排序更加簡單一點,可能是因為氣泡排序是我接觸的第一個排序吧,所以我的程式碼中幾乎都是用冒泡來進行排序的 - 密碼的輸入顯示 *
void show1()
{
char cipher[20]={"123456"},a[20],t;//cioher 表示密碼
int i,j;
printf("歡迎進入學生資訊管理系統\n");
for(i=0;i<3;i++)
{
printf("請輸入管理員密碼:");
for(j=0;a[j-1]!=13;j++)//輸入時回車時,停止錄入密碼
{
a[j]=getch();//getch接受鍵盤輸入字元,不顯示到螢幕上
if(a[j]==8&&j>0)//如果輸入的是刪除鍵
{
printf("\b \b");//用\b和空格覆蓋前面的*
j-=2;//刪除陣列中的字元
}
else if(j>=0)
printf("*");
else //防止刪除提示語句
printf(" ");
}
printf("\n");
a[j-1]='\0';
if(strcmp(cipher,a)==0)
return;
}
printf("三次輸入錯誤!!!退出系統\n");
Sleep(150);
exit(1);
}
5. 原始碼
學生資訊管理2.0版
這個版中,剛剛學習了檔案的相關操作,所以將檔案的操作加入到其中。
1. 新增功能
- 從檔案中錄入資料
- 可以選擇多種順序輸出
- 將學生資訊儲存到檔案中
- 使用多檔案儲存不同功能的函式
2. 函式框架
int main(void)
{
struct student *pHead;
int flag;
show1();//登入介面
pHead=startup();//資訊的錄入
save_3(pHead);//儲存到快取檔案中
while(1)
{
system("cls");
show3();
fflush(stdin);
scanf("%d",&flag);
switch(flag)
{
case 1:increase(pHead);break;//增加
case 2:strike_out(pHead);break;//刪除
case 3:chang(pHead);break;//修改
case 4:inquiry(pHead);break;//查詢
case 5:save_3(pHead);
output(pHead);
pHead=finput(1);break;//輸出
case 6:
save_3(pHead);
save(pHead);
pHead=finput(1);break;//儲存
case 0:exit(0);break;
default :printf("輸入有誤請重新輸入\n");break;
}
printf("按任意鍵進行下一步操作\n");
getch();
}
}
3. 函式呼叫關係圖
4. 部分功能函式
- 檔案的讀
struct student *finput(int a)//檔案錄入 a控制是否需要輸入檔名
{
FILE *fp;
struct student *pHead=NULL,*pEnd,*pNew;
int sum=0,i,j,num;
char filename[100]=N;
if(a==2)
{
printf("請輸入檔案路徑及檔名:");
fflush(stdin);
gets(filename);
}
iCound=0;
pEnd=pHead=(struct student *)malloc(sizeof(struct student));
fp=fopen(filename,"rt+");
if(fp==NULL)
{
printf("不能開啟檔案");
exit(1);
}
while(1)
{
sum=0;
pNew=(struct student *)malloc(sizeof(struct student));
fscanf(fp,"%s %s %s",pNew->name,pNew->num,pNew->classes);
fscanf(fp,"%s %s %s",pNew->score[0],pNew->score[1],pNew->score[2]);
for(i=0;i<3;i++)//字串轉換為整數
{
num=0;
for(j=0;pNew->score[i][j];j++)
num=num*10+pNew->score[i][j]-'0';
sum=sum+num;
}
pNew->aver=sum*1.0/3;
if(feof(fp))
break;
pEnd->next=pNew;
pEnd=pNew;
iCound++;
}
pEnd->next=NULL;
fclose(fp);
return pHead;
}
- 檔案的寫
void save_3(struct student *pHead)
{
FILE *fp;
char filename[100]= N;
fp=fopen(filename,"wt");
if(fp==NULL)
{
printf("不能開啟檔案");
exit(1);
}
pHead=pHead->next;
while(pHead)
{
fprintf(fp,"%s %s %s ",pHead->name,pHead->num,pHead->classes);
fprintf(fp,"%s %s %s\n",pHead->score[0],pHead->score[1],pHead->score[2]);
pHead=pHead->next;
}
fclose(fp);
}
- 使用引數多次呼叫排序函式
void output_2(struct student *pHead,int a)//a控制排序依據 //方式2輸出
{
int i,j,flag;
struct student *pj_1,*pj,*pj_h;
for(i=0;i<iCound-1;i++)
for(j=0,pj=pHead,flag=0;j<iCound-i-1;j++)
{
if(flag==0)
{
pj_1=pj;
pj=pj->next;
pj_h=pj->next;
}
if(flag==1)
{
pj_1=pj_1->next;
pj_h=pj->next;
}
flag=0;
if(a==2&&(pj->aver)<(pj_h->aver))
{
exchange(pj,pj_h,pj_1);
flag=1;
}
else if(a==3&&strcmp(pj->num,pj_h->num)==1)
{
exchange(pj,pj_h,pj_1);
flag=1;
}
else if(a==4&&strcmp(pj->classes,pj_h->classes)==1)
{
exchange(pj,pj_h,pj_1);
flag=1;
}
else if(a==5&&strcmp(pj->name,pj_h->name)==1)
{
exchange(pj,pj_h,pj_1);
flag=1;
}
}
output_t(pHead);
}
5. 原始碼
這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址
學生資訊管理3.0版
這個版本具體可以看我的上一篇部落格。
1. 新增功能
- 位運算對密碼的加密
- 分為三個登入端,學生,教師,管理員
2.原始碼
這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址
學生資訊管理4.0版
1. 新增功能
- 從管理一個班變為管理五個班
- 對學生資訊的資料結構進行改進,將儲存成績從二維陣列改為連結串列,即十字連結串列。(老師加的要求)
2. 函式框架
3. 函式呼叫關係圖
4. 部分功能函式
- 學生資訊結構節點的定義
struct score//分數
{
char date[20];
int No;
struct score *next;
};
struct student
{
int No; //排名
char name[20];//姓名
char num[20];//學號
char classes[20];//班級
struct score *ScorepHead;//分數
double aver;//平均分
struct student *next;//指標域
};
struct student *StupHead[6]; //5個班的頭節點
int iCound[6];//5個班的節點數量
- 學生資訊連結串列的建立(檔案讀入)
struct student *Finput(char filename[])
{
FILE *fp;
struct student *pHead=NULL,*pEnd,*pNew;
int sum=0,i,j,num;
iCound[filename[5]-'0'-1]=0;
pEnd=pHead=(struct student *)malloc(sizeof(struct student));
fp=fopen(filename,"rt");
if(fp==NULL)
{
printf("不能開啟檔案");
exit(1);
}
char a[20];//暫存資訊
fscanf(fp,"%s",a);
int temp[Classnum]={0};//暫存科目數量
while(!feof(fp))
{
sum=0;
pNew=(struct student *)malloc(sizeof(struct student));
strcpy(pNew->name,a);
fscanf(fp,"%s %s",pNew->num,pNew->classes);
struct score *spEnd,*spNew,*spt; //錄入科目成績
pNew->ScorepHead=spEnd=(struct score *)malloc(sizeof(struct score));
while(1)
{
spNew=(struct score *)malloc(sizeof(struct score));
fscanf(fp,"%s",a);
if(a[0]<'0'||a[0]>'9'||feof(fp))
break;
strcpy(spNew->date,a);
spEnd->next=spNew;
spEnd=spNew;
}
spEnd->next=NULL;
int k;
for(k=0,spt=pNew->ScorepHead->next;spt!=NULL;spt=spt->next,k++)//字串轉整數
{
for(j=0,num=0;spt->date[j];j++)
num=num*10+spt->date[j]-'0';
sum=sum+num;
temp[k]++;
}
pNew->aver=sum/k;
iCound[filename[5]-'0'-1]++;
pEnd->next=pNew;
pEnd=pNew;
}
for(i=0;i<Classnum;i++)
subject[filename[5]-'0'-1][i]=temp[i];
pEnd->next=NULL;
fclose(fp);
return pHead;
}
5. 原始碼
這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址