?? 學生成績管理系統源代碼.c
字號:
#include "stdio.h" /*I/O函數*/
#include "stdlib.h" /*其它說明*/
#include "string.h" /*字符串函數*/
#include "conio.h" /*屏幕操作函數*/
#include "mem.h" /*內存操作函數*/
#include "ctype.h" /*字符操作函數*/
#include "alloc.h" /*動態地址分配函數*/
#define N 3 /*定義常數*/
typedef struct z1 /*定義數據結構*/
{ char no[11];
char name[15];
int score[N];
float sum;
float average;
int order;
struct z1 *next;
}STUDENT;
/*菜單函數,返回值為整數*/
menu_select()
{
char *menu[]={" ***************MENU***************", /*定義菜單字符串數組*/
" 0. Enter list", /*輸入記錄*/
" 1. Print list", /*顯示單鏈表中所有記錄*/
" 2. Sort to make new file ", /*按照總成績排序*/
" 3. sort to Single course result", /*按照單科成績排序*/
" 4. Search record on ID", /*按照學號查找記錄*/
" 5. Insert record to list ", /*插入記錄到表中*/
" 6. Delete a record from list", /*從表中刪除記錄*/
" 7. Save the file", /*將單鏈表中記錄保存到文件中*/
" 8. Load the file", /*從文件中讀入記錄*/
" 9. Quit", /*退出*/
" ",
" ", /*屏幕調節,沒有實際意義*/
" ",
" ***********************************",
" ",
" ",};
char s[3]; /*以字符形式保存選擇號*/
int c,i; /*定義整形變量*/
textbackground(YELLOW); /*設置背景顏色為藍色*/
gotoxy(1,25); /*移動光標*/
printf("Press any key enter menu......\n"); /*壓任一鍵進入主菜單*/
getch(); /*輸入任一鍵*/
clrscr(); /*清屏*/
for(i=0;i<16;i++) /*輸出主菜單數組*/
{ gotoxy(10,i+1);
cprintf("%s",menu[i]);
}
window(1,1,80,25); /*恢復原窗口大小*/
gotoxy(10,21); /*移動光標*/
do{printf("\n Enter you choice(0~9):"); /*在菜單窗口外顯示提示信息*/
scanf("%s",s); /*輸入選擇項*/
c=atoi(s); /*將輸入的字符串轉化為整形數*/
}while(c<0||c>9); /*選擇項不在0~9之間重輸*/
return c; /*返回選擇項,主程序根據該數調用相應的函數*/
}
/*初始化鏈表,可以實現對另一組數據的處理*/
STUDENT *init() /*初始化鏈表*/
{ return NULL;}
/*創建鏈表,完成數據錄入功能*/
STUDENT *create()
{ int i; int s;
STUDENT *h=NULL,*info; /* STUDENT指向結構體的指針*/
for(;;)
{ info=(STUDENT *)malloc(sizeof(STUDENT)); /*申請空間*/
if(!info) /*如果指針info為空*/
{
printf("\nOut of memory"); /*輸出內存溢出*/
return NULL; /*返回空指針*/
}
printf("Input imformation as follow.\n");
printf("Press '#'after'Enter NO'to end the input.\n");
inputs("Enter NO.:",info->no,11); /*輸入學號并校驗*/
if(info->no[0]=='#') break; /*如果學號首字符為#則結束輸入*/
inputs("Enter name:",info->name,15); /*輸入姓名,并進行校驗*/
printf("Please input %d scores \n",N); /*提示開始輸入成績*/
s=0; /*計算每個學生的總分,初值為0*/
for(i=0;i<N;i++) /*N門課程循環N次*/
{
do{
printf("score%d:",i+1); /*提示輸入第幾門課程*/
scanf("%d",&info->score[i]); /*輸入成績*/
if(info->score[i]>100||info->score[i]<0)/*確保成績在0~100之間*/
printf("Bad data,repeat input\n"); /*出錯提示信息*/
}while(info->score[i]>100||info->score[i]<0);
s=s+info->score[i]; /*累加各門課程成績*/
}
info->sum=s; /*將總分保存*/
info->average=(float)s/N; /*求出平均值*/
info->order=0; /*未排序前此值為0*/
info->next=h; /*將頭結點做為新輸入結點的后繼結點*/
h=info; /*新輸入結點為新的頭結點*//*沒排序前,后輸入的數據將排在最上*/
}
return(h); /*返回頭指針*/
}
/*自定義輸入控制函數inputs*/
inputs(char *prompt, char *s, int count)
{
char p[255];
do{printf(prompt); /*顯示提示信息*/
scanf("%s",p); /*輸入字符串*/
if(strlen(p)>count)printf("\n Too long! \n"); /*進行長度校驗,超過count值重輸入*/
}while(strlen(p)>count);
strcpy(s,p); /*將輸入的字符串拷貝到字符串s中*/
}
/*顯示模塊*/
void print(STUDENT *h)
{ int i=0; /* 統計記錄條數*/
STUDENT *p; /*移動指針*/
clrscr(); /*清屏*/
p=h; /*初值為頭指針*/
printf("\n\n\n****************************STUDENT**********************************\n");
printf("|rec|NO. | name | sc1| sc2| sc3| ave |order|\n");
printf("|---|----------|---------------|----|----|----|-------|-----|\n");
while(p!=NULL)
{ i++;
if(i%15==0){getch();clrscr();
printf("\n\n\n\n");} /*否則什么也不做*/
else;
printf("|%2d |%-10s|%-15s|%4d|%4d|%4d| %4.2f | %3d |\n", i, p->no,p->name,p->score[0],p->score[1],
p->score[2],p->average,p->order);
p=p->next;
}
printf("**********************************end*********************************\n");
}
/*排序模塊*/
STUDENT *sort(STUDENT *h)
{
int i=0; /*用來保存名次*/
STUDENT *p,*q,*t,*h1; /*定義臨時指針*/
h1=h->next; /*將原表的頭指針所指的下一個結點作頭指針*/
h->next=NULL; /*斷開原來鏈表頭結點與其它結點的連接*/
while(h1!=NULL) /*當原表不為空時,進行排序*/
{ t=h1; /*取原表的頭結點*/
h1=h1->next; /*原表頭結點指針后移*/
p=h; /*設定移動指針p,從頭指針開始*/
q=h; /*設定移動指針q做為p的前驅,初值為頭指針*/
while(t->sum<p->sum&&p!=NULL) /*作總分比較*/
{ q=p; /*待插入點值小,則新表指針后移*/
p=p->next;
}
if(p==q) /*p==q,上面的while沒有執行,也即插入點大于頭指針,此點應排在首位*/
{ t->next=p; /*待排序點的后繼為p*/
h=t; /*新頭結點為待排序點*/
}
else /*待排序點應插入在q和p之間,如p為空則是尾部*/
{ t->next=p; /*t的后繼是p*/
q->next=t; /*q的后繼是t*/
}
}
p=h; /*已排好序的頭指針賦給p*/
while(p!=NULL) /*賦予各組數據排序號*/
{
i++; /*結點序號*/
p->order=i; /*將名次賦值*/
p=p->next; /*指針后移*/
}
printf("Sort sucess!!!\n"); /*排序成功*/
return (h); /*返回頭指針*/
}
/*查找記錄模塊*/
void search(STUDENT *h)
{ STUDENT *p; /*移動指針*/
char s[15]; /*存放姓名的字符數組*/
clrscr(); /*清屏幕*/
printf("Input the ID that you want to search:\n");
scanf("%s",s); /*輸入姓名*/
p=h; /*將頭指針賦給p*/
while(strcmp(p->no,s)&&p!=NULL)/*當記錄的姓名不是要找的,并且指針不為空時*/
p=p->next; /*移動指針,指向下一結點,繼續查找*/
if(p==NULL) /*指針為空,說明未能找到所要的結點*/
printf("\nCan find the student who ID is %s\n",s);
else /*顯示找到的記錄信息*/
{ printf("\n\n*****************************havefound***************************\n");
printf("|NO. | name | sc1| sc2| sc3| ave |order|\n");
printf("|----------|---------------|----|----|----|--------|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %3d |\n",
p->no,p->name,p->score[0],p->score[1],p->score[2],p->average,p->order);
printf("********************************end*******************************\n");
}
}
/*插入記錄模塊*/
STUDENT *insert(STUDENT *h)
{ STUDENT *p,*q,*info,*k; /*p指向插入位置,q是其前驅,info指新插入記錄*/
int s1,i,n=0;
printf("\nplease new record\n");
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申請空間*/
if(!info)
{ printf("\Out of memory"); /*如沒有申請到,內存溢出*/
return NULL; /*返回空指針*/
}
inputs("Enter NO.:",info->no,11); /*以下是待插入數據的錄入和處理,具體同創建模塊同*/
inputs("Enter name:",info->name,15);
printf("Please input %d score \n",N);
s1=0;
for(i=0;i<N;i++)
{ do{
printf("score%d:",i+1);
scanf("%d",&info->score[i]);
if(info->score[i]>100||info->score[i]<0)
printf("bad data,repeat input\n");
}while(info->score[i]>100||info->score[i]<0);
s1=s1+info->score[i];
}
info->sum=s1;
info->average=(float)s1/N;
info->next=NULL; /*設后繼指針為空*/
p=h; /*將指針賦值給p*/
q=h; /*將指針賦值給q*/
if(h==NULL) /*鏈表為空*/
{h=info;info->next=NULL;}
else
{while((info->sum<p->sum)&&(p->next!=NULL))
{q=p; /*使q指向p剛才的結點*/
p=p->next;} /*使p后移一個結點*/
if(info->sum>=p->sum)
{if(h==p){h=info; info->next=p;} /*info作為頭指針,p作為info的后繼指針*/
else q->next=info; /*q的后繼指針是info*/
info->next=p;} /*info的后繼指針是p*/
else
{p->next=info;info->next=NULL;}} /*p的后繼指針是info,info的后繼指針是空*/
k=h;
while(k!=NULL) /*重新賦予排序號(排序號因為被插入新數據而改變)*/
{ n++;
k->order=n;
k=k->next;
}
printf("\n ----have inserted %s student----\n",info->name);
return(h);
/*返回頭指針*/
/* ) */
} /* 只是修改 將“)” 換成 “}” 就可以了, 就這么一個錯誤 */
/*刪除記錄模塊*/
STUDENT *delete(STUDENT *h)
{ char k[5]; /*定義字符串數組,用來確認刪除信息*/
STUDENT *p,*q; /*p為查找到要刪除的結點指針,q為其前驅指針*/
char s[11]; /*存放學號*/
clrscr(); /*清屏*/
printf("Please deleted no\n"); /*顯示提示信息*/
scanf("%s",s); /*輸入要刪除記錄的學號*/
q=p=h; /*給q和p賦初值頭指針*/
while(strcmp(p->no,s)&&p!=NULL) /*當記錄的學號不是要找的,或指針不為空時*/
{ q=p; /*將p指針值賦給q作為p的前驅指針*/
p=p->next; /*將p指針指向下一條記錄*/
}
if(p==NULL) /*如果p為空,說明鏈表中沒有該結點*/
printf("\nlist no %s student\n",s);
else /*p不為空,顯示找到的記錄信息*/
{ printf("*****************************have found***************************\n");
printf("|no | name | sc1| sc2| sc3| ave |order|\n");
printf("|----------|---------------|----|----|----|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %3d |\n", p->no,
p->name,p->score[0],p->score[1],p->score[2],p->average,p->order);
printf("********************************end*******************************\n");
do{inputs("Do you really want to deleted?(y/n)",k,5);
}while(k[0]!='y'&&k[0]!='n');
if(k[0]!='n') /*刪除確認判斷*/
{if(p==h) /*如果p==h,說明被刪結點是頭結點*/
h=p->next; /*修改頭指針指向下一條記錄*/
else
q->next=p->next; /*不是頭指針,將p的后繼結點作為q的后繼結點*/
free(p); /*釋放p所指結點空間*/
printf("\n have deleted No %s student\n",s);
}}
return(h); /*返回頭指針*/
}
/*保存數據到文件模塊*/
void save(STUDENT *h)
{
FILE *fp; /*定義指向文件的指針*/
STUDENT *p; /* 定義移動指針*/
char outfile[20]; /*保存輸出文件名*/
printf("Enter outfile name,for example G:\\f1\\score.txt:\n");
scanf("%s",outfile);
if((fp=fopen(outfile,"wb"))==NULL) /*為輸出打開一個二進制文件,如沒有則建立*/
{
printf("Can not open file\n");
exit(1);
}
printf("\nSaving file......\n"); /*打開文件,提示正在保存*/
p=h; /*移動指針從頭指針開始*/
while(p!=NULL) /*如p不為空*/
{
fwrite(p,sizeof(STUDENT),1,fp); /*寫入一條記錄*/
p=p->next; /*指針后移*/
}
fclose(fp); /*關閉文件*/
printf("-----Save success!!-----\n"); /*顯示保存成功*/
}
/*導入信息模塊*/
STUDENT *load()
{ STUDENT *p,*q,*h=NULL; /*定義記錄指針變量*/
FILE *fp; /* 定義指向文件的指針*/
char infile[20]; /*保存文件名*/
printf("Enter infile name,for example G:\\f1\\score.txt:\n");
scanf("%s",infile); /*輸入文件名*/
if((fp=fopen(infile,"rb"))==NULL) /*打開一個二進制文件,為讀方式*/
{ printf("Can not open file\n"); /*如不能打開,返回頭指針*/
return h;
}
printf("\n -----Loading file!-----\n");
p=(STUDENT *)malloc(sizeof(STUDENT)); /*申請空間*/
if(!p)
{ printf("Out of memory!\n"); /*如沒有申請到,則內存溢出*/
return h; /*返回空頭指針*/
}
h=p; /*申請到空間,將其作為頭指針*/
while(!feof(fp)) /*循環讀數據直到文件尾結束*/
{ if(1!=fread(p,sizeof(STUDENT),1,fp))
break; /*如果沒讀到數據,跳出循環*/
p->next=(STUDENT *)malloc(sizeof(STUDENT)); /*為下一個結點申請空間*/
if(!p->next)
{
printf("Out of memory!\n"); /*如沒有申請到,則內存溢出*/
return h;
}
q=p; /*保存當前結點的指針,作為下一結點的前驅*/
p=p->next; /*指針后移,新讀入數據鏈到當前表尾*/
}
q->next=NULL; /*最后一個結點的后繼指針為空*/
fclose(fp); /*關閉文件*/
printf("Load success!!!\n");
return h; /*返回頭指針*/
}
STUDENT *sort1(STUDENT *h)
{
int i=0,j;
STUDENT *p,*q,*t,*h1;
printf("Enter according to which the number of courses to be sorted :(0.sc1 1.sc2 2.sc3)\n");
scanf("%d",&j);
h1=h->next;
h->next=NULL;
while(h1!=NULL)
{
t=h1;
h1=h1->next;
p=h;
q=h;
while(t->score[j]<p->score[j]&&p!=NULL)
{
q=p;
p=p->next;
}
if(p==q)
{
t->next=p;
h=t;
}
else
{
t->next=p;
q->next=t;
}
}
p=h;
while(p!=NULL)
{
i++;
p->order=i;
p=p->next;
}
print(h);
printf("Sort success !!!\n");
return (h);
}
/******主函數開始*******/
main()
{int i;
STUDENT *head; /*鏈表定義頭指針*/
head=init(); /*初始化鏈表*/
clrscr(); /*清屏*/
for(;;) /*無限循環*/
{switch(menu_select()) /*調用主菜單函數,返回值整數作開關語句的條件*/
{
case 3:head=sort1(head);break; /*執行初始化*/
case 0:head=create();break; /*創建鏈表*/
case 1:print(head);break; /*顯示全部記錄*/
case 2:head=sort(head);break; /*排序*/
case 4:search(head);break; /*查找記錄*/
case 5:head=insert(head); break; /*插入記錄*/
case 6:head=delete(head);break; /*刪除記錄*/
case 7:save(head);break; /*保存文件*/
case 8:head=load(); break; /*讀文件*/
case 9:exit(0); /*如菜單返回值為9程序結束*/
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -