c語言學生成績管理系統源碼
#include?"stdio.h"???/*標準輸入輸出函數庫*/
#include?"stdlib.h"??/*標準函數庫*/
#include?"string.h"??/*字符串函數庫*/
#include?"conio.h"????/*屏幕操作函數庫*/
#define?HEADER1?"??????----------------------------STUDENT----------------------------------??\n"
#define?HEADER2?"?????|????number?????|??????name?????|Comp|Math|Eng?|???sum??|??ave??|mici?|?\n"
#define?HEADER3?"?????|---------------|---------------|----|----|----|--------|-------|-----|?"
#define?FORMAT??"????????|????%-10s?|%-15s|%4d|%4d|%4d|?%4d???|?%.2f?|%4d?|\n"
#define?DATA??p->data.num,p->data.name,p->data.egrade,p->data.mgrade,p->data.cgrade,p->data.total,p->data.ave,p->data.mingci
#define?END?????"???????---------------------------------------------------------------------?\n"
int?saveflag=0;??/*是否需要存盤的標志變量*/
/*定義與學生有關的數據結構*/
typedef?struct?student??????/*標記為student*/
{
char?num[10];???/*學號*/
char?name[15];??/*姓名*/
int?cgrade;?????/*C語言成績*/
int?mgrade;?????/*數學成績*/
int?egrade;?????/*英語成績*/
int?total;??????/*總分*/
float?ave;??????/*平均分*/
int?mingci;?????/*名次*/
};
/*定義每條記錄或結點的數據結構,標記為:node*/
typedef?struct?node
{
struct?student?data;??/*數據域*/
struct?node?*next;????/*指針域*/
}Node,*Link;???/*Node為node類型的結構變量,*Link為node類型的指針變量*/
void?menu()??/*主菜單*/
{
system("cls");???/*調用DOS命令,清屏.與clrscr()功能相同*/
textcolor(10);???/*在文本模式中選擇新的字符顏色*/
gotoxy(10,5);?????/*在文本窗口中設置光標*/
cprintf("?????????????????The?Students'?Grade?Management?System?\n");
gotoxy(10,8);
cprintf("?????*************************Menu********************************\n");
gotoxy(10,9);
cprintf("?????*??1?input???record?????????????2?delete?record?????????????*\n");
gotoxy(10,10);
cprintf("?????*??3?search??record?????????????4?modify?record?????????????*\n");
gotoxy(10,11);
cprintf("?????*??5?insert??record?????????????6?count??record?????????????*\n");
gotoxy(10,12);
cprintf("?????*??7?sort????reord??????????????8?save???record?????????????*\n");
gotoxy(10,13);
cprintf("?????*??9?display?record?????????????0?quit???system?????????????*\n");
gotoxy(10,14);
cprintf("?????*************************************************************\n");
/*cprintf()送格式化輸出至文本窗口屏幕中*/
}
void?printheader()?/*格式化輸出表頭*/
{
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
}
void?printdata(Node?*pp)?/*格式化輸出表中數據*/
{
Node*?p;
p=pp;
printf(FORMAT,DATA);
}
void?Wrong()??/*輸出按鍵錯誤信息*/
{
printf("\n\n\n\n\n***********Error:input?has?wrong!?press?any?key?to?continue**********\n");
getchar();
}
void?Nofind()??/*輸出未查找此學生的信息*/
{
printf("\n=====>Not?find?this?student!\n");
}
void?Disp(Link?l)??/*顯示單鏈表l中存儲的學生記錄,內容為student結構中定義的內容*/
{
Node?*p;
p=l->next;?/*l存儲的是單鏈表中頭結點的指針,該頭結點沒有存儲學生信息,指針域指向的后繼結點才有學生信息*/
if(!p)??/*p==NULL,NUll在stdlib中定義為0*/
{
printf("\n=====>Not?student?record!\n");
getchar();
return;
}
printf("\n\n");
printheader();?/*輸出表格頭部*/
while(p)????/*逐條輸出鏈表中存儲的學生信息*/
{
printdata(p);
p=p->next;??/*移動至下一個結點*/
printf(HEADER3);
}
getchar();
}
/*************************************************************
作用:用于定位鏈表中符合要求的節點,并返回指向該節點的指針
參數:findmess[]保存要查找的具體內容;?nameornum[]保存按什么查找;
在單鏈表l中查找;
**************************************************************/
Node*?Locate(Link?l,char?findmess[],char?nameornum[])
{
Node?*r;
if(strcmp(nameornum,"num")==0)?/*按學號查詢*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.num,findmess)==0)?/*若找到findmess值的學號*/
return?r;
r=r->next;
}
}
else?if(strcmp(nameornum,"name")==0)??/*按姓名查詢*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.name,findmess)==0)????/*若找到findmess值的學生姓名*/
return?r;
r=r->next;
}
}
return?0;?/*若未找到,返回一個空指針*/
}
/*輸入字符串,并進行長度驗證(長度 void?stringinput(char?*t,int?lens,char?*notice) { char?n[255]; do{ printf(notice);??/*顯示提示信息*/ scanf("%s",n);??/*輸入字符串*/ if(strlen(n)>lens)printf("\n?exceed?the?required?length!?\n");?/*進行長度校驗,超過lens值重新輸入*/ }while(strlen(n)>lens); strcpy(t,n);?/*將輸入的字符串拷貝到字符串t中*/ } /*輸入分數,0<=分數<=100)*/ int?numberinput(char?*notice) { int?t=0; do{ printf(notice);??/*顯示提示信息*/ scanf("%d",&t);??/*輸入分數*/ if(t>100?||?t<0)?printf("\n?score?must?in?[0,100]!?\n");?/*進行分數校驗*/ }while(t>100?||?t<0); return?t; } /*增加學生記錄*/ void?Add(Link?l) { Node?*p,*r,*s;??/*實現添加操作的臨時的結構體指針變量*/ char?ch,flag=0,num[10]; r=l; s=l->next; system("cls"); Disp(l);?/*先打印出已有的學生信息*/ while(r->next!=NULL) r=r->next;?/*將指針移至于鏈表最末尾,準備添加記錄*/ while(1)?/*一次可輸入多條記錄,直至輸入學號為0的記錄結點添加操作*/ { while(1)?/*輸入學號,保證該學號沒有被使用,若輸入學號為0,則退出添加記錄操作*/ { stringinput(num,10,"input?number(press?'0'return?menu):");?/*格式化輸入學號并檢驗*/ flag=0; if(strcmp(num,"0")==0)?/*輸入為0,則退出添加操作,返回主界面*/ {return;} s=l->next; while(s)?/*查詢該學號是否已經存在,若存在則要求重新輸入一個未被占用的學號*/ { if(strcmp(s->data.num,num)==0) { flag=1; break; } s=s->next; } if(flag==1)?/*提示用戶是否重新輸入*/ {??getchar(); printf("=====>The?number?%s?is?not?existing,try?again?(y/n):",num); scanf("%c",&ch); if(ch=='y'||ch=='Y') continue; else return; } else {break;} } p=(Node?*)malloc(sizeof(Node));?/*申請內存空間*/ if(!p) { printf("\n?allocate?memory?failure?");?/*如沒有申請到,打印提示信息*/ return?;?????????????/*返回主界面*/ } strcpy(p->data.num,num);?/*將字符串num拷貝到p->data.num中*/ stringinput(p->data.name,15,"Name:"); p->data.cgrade=numberinput("C?language?Score[0-100]:");?/*輸入并檢驗分數,分數必須在0-100之間*/ p->data.mgrade=numberinput("Math?Score[0-100]:");???/*輸入并檢驗分數,分數必須在0-100之間*/ p->data.egrade=numberinput("English?Score[0-100]:");?/*輸入并檢驗分數,分數必須在0-100之間*/ p->data.total=p->data.egrade+p->data.cgrade+p->data.mgrade;?/*計算總分*/ p->data.ave=(float)(p->data.total/3);??/*計算平均分*/ p->data.mingci=0; p->next=NULL;?/*表明這是鏈表的尾部結點*/ r->next=p;??/*將新建的結點加入鏈表尾部中*/ r=p; saveflag=1; } return?; } void?Qur(Link?l)?/*按學號或姓名,查詢學生記錄*/ { int?select;?/*1:按學號查,2:按姓名查,其他:返回主界面(菜單)*/ char?searchinput[20];?/*保存用戶輸入的查詢內容*/ Node?*p; if(!l->next)?/*若鏈表為空*/ { system("cls"); printf("\n=====>No?student?record!\n"); getchar(); return; } system("cls"); printf("\n?????=====>1?Search?by?number??=====>2?Search?by?name\n"); printf("??????please?choice[1,2]:"); scanf("%d",&select); if(select==1)???/*按學號查詢*/ { stringinput(searchinput,10,"input?the?existing?student?number:"); p=Locate(l,searchinput,"num");/*在l中查找學號為searchinput值的節點,并返回節點的指針*/ if(p)?/*若p!=NULL*/ { printheader(); printdata(p); printf(END); printf("press?any?key?to?return"); getchar(); } else Nofind(); getchar(); } else?if(select==2)?/*按姓名查詢*/ { stringinput(searchinput,15,"input?the?existing?student?name:"); p=Locate(l,searchinput,"name"); if(p) { printheader(); printdata(p); printf(END); printf("press?any?key?to?return"); getchar(); } else Nofind(); getchar(); } else Wrong(); getchar(); } /*刪除學生記錄:先找到保存該學生記錄的節點,然后刪除該節點*/ void?Del(Link?l) { int?sel; Node?*p,*r; char?findmess[20]; if(!l->next) {?system("cls"); printf("\n=====>No?student?record!\n"); getchar(); return; } system("cls"); Disp(l); printf("\n????????=====>1?Delete?by?number???????=====>2?Delete?by?name\n"); printf("???????please?choice[1,2]:"); scanf("%d",&sel); if(sel==1) { stringinput(findmess,10,"input?the?existing?student?number:"); p=Locate(l,findmess,"num"); if(p)??/*p!=NULL*/ { r=l; while(r->next!=p) r=r->next; r->next=p->next;/*將p所指節點從鏈表中去除*/ free(p);?/*釋放內存空間*/ printf("\n=====>delete?success!\n"); getchar(); saveflag=1; } else Nofind(); getchar(); } else?if(sel==2)?/*先按姓名查詢到該記錄所在的節點*/ { stringinput(findmess,15,"input?the?existing?student?name"); p=Locate(l,findmess,"name"); if(p) { r=l; while(r->next!=p) r=r->next; r->next=p->next; free(p); printf("\n=====>delete?success!\n"); getchar(); saveflag=1; } else Nofind(); getchar(); } else Wrong(); getchar(); } /*修改學生記錄。先按輸入的學號查詢到該記錄,然后提示用戶修改學號之外的值,學號不能修改*/ void?Modify(Link?l) { Node?*p; char?findmess[20]; if(!l->next) {?system("cls"); printf("\n=====>No?student?record!\n"); getchar(); return; } system("cls"); printf("modify?student?recorder"); Disp(l); stringinput(findmess,10,"input?the?existing?student?number:");?/*輸入并檢驗該學號*/ p=Locate(l,findmess,"num");?/*查詢到該節點*/ if(p)?/*若p!=NULL,表明已經找到該節點*/ { printf("Number:%s,\n",p->data.num); printf("Name:%s,",p->data.name); stringinput(p->data.name,15,"input?new?name:"); printf("C?language?score:%d,",p->data.cgrade); p->data.cgrade=numberinput("C?language?Score[0-100]:"); printf("Math?score:%d,",p->data.mgrade); p->data.mgrade=numberinput("Math?Score[0-100]:"); printf("English?score:%d,",p->data.egrade); p->data.egrade=numberinput("English?Score[0-100]:"); p->data.total=p->data.egrade+p->data.cgrade+p->data.mgrade; p->data.ave=(float)(p->data.total/3); p->data.mingci=0; printf("\n=====>modify?success!\n"); Disp(l); saveflag=1; } else Nofind(); getchar(); } /*插入記錄:按學號查詢到要插入的節點的位置,然后在該學號之后插入一個新節點。*/ void?Insert(Link?l) { Link?p,v,newinfo;?/*p指向插入位置,newinfo指新插入記錄*/ char?ch,num[10],s[10];??/*s[]保存插入點位置之前的學號,num[]保存輸入的新記錄的學號*/ int?flag=0; v=l->next; system("cls"); Disp(l); while(1) {?stringinput(s,10,"please?input?insert?location??after?the?Number:"); flag=0;v=l->next; while(v)?/*查詢該學號是否存在,flag=1表示該學號存在*/ { if(strcmp(v->data.num,s)==0)??{flag=1;break;} v=v->next; } if(flag==1) break;?/*若學號存在,則進行插入之前的新記錄的輸入操作*/ else {??getchar(); printf("\n=====>The?number?%s?is?not?existing,try?again?(y/n):",s); scanf("%c",&ch); if(ch=='y'||ch=='Y') {continue;} else {return;} } } /*以下新記錄的輸入操作與Add()相同*/ stringinput(num,10,"input?new?student?Number:"); v=l->next; while(v) { if(strcmp(v->data.num,num)==0) { printf("=====>Sorry,the?new?number:'%s'?is?existing?!\n",num); printheader(); printdata(v); printf("\n"); getchar(); return; } v=v->next; } newinfo=(Node?*)malloc(sizeof(Node)); if(!newinfo) { printf("\n?allocate?memory?failure?");?/*如沒有申請到,打印提示信息*/ return?;?????????????/*返回主界面*/ } strcpy(newinfo->data.num,num); stringinput(newinfo->data.name,15,"Name:"); newinfo->data.cgrade=numberinput("C?language?Score[0-100]:"); newinfo->data.mgrade=numberinput("Math?Score[0-100]:"); newinfo->data.egrade=numberinput("English?Score[0-100]:"); newinfo->data.total=newinfo->data.egrade+newinfo->data.cgrade+newinfo->data.mgrade; newinfo->data.ave=(float)(newinfo->data.total/3); newinfo->data.mingci=0; newinfo->next=NULL; saveflag=1;?/*在main()有對該全局變量的判斷,若為1,則進行存盤操作*/ /*將指針賦值給p,因為l中的頭節點的下一個節點才實際保存著學生的記錄*/ p=l->next; while(1) { if(strcmp(p->data.num,s)==0)?/*在鏈表中插入一個節點*/ { newinfo->next=p->next; p->next=newinfo; break; } p=p->next; } Disp(l); printf("\n\n"); getchar(); } /*統計該班的總分第一名和單科第一,和各科不及格人數*/ void?Tongji(Link?l) { Node?*pm,*pe,*pc,*pt;?/*用于指向分數最高的節點*/ Node?*r=l->next; int?countc=0,countm=0,counte=0;?/*保存三門成績中不及格的人數*/ if(!r) {?system("cls"); printf("\n=====>Not?student?record!\n"); getchar(); return?; } system("cls"); Disp(l); pm=pe=pc=pt=r; while(r) { if(r->data.cgrade<60)?countc++; if(r->data.mgrade<60)?countm++; if(r->data.egrade<60)?counte++; if(r->data.cgrade>=pc->data.cgrade)????pc=r; if(r->data.mgrade>=pm->data.mgrade)????pm=r; if(r->data.egrade>=pe->data.egrade)????pe=r; if(r->data.total>=pt->data.total)??????pt=r; r=r->next; } printf("\n------------------------------the?TongJi?result--------------------------------\n"); printf("C?Language<60:%d?(ren)\n",countc); printf("Math??????<60:%d?(ren)\n",countm); printf("English???<60:%d?(ren)\n",counte); printf("-------------------------------------------------------------------------------\n"); printf("The?highest?student?by?total???scroe???name:%s?totoal?score:%d\n",pt->data.name,pt->data.total); printf("The?highest?student?by?English?score???name:%s?totoal?score:%d\n",pe->data.name,pe->data.egrade); printf("The?highest?student?by?Math????score???name:%s?totoal?score:%d\n",pm->data.name,pm->data.mgrade); printf("The?highest?student?by?C???????score???name:%s?totoal?score:%d\n",pc->data.name,pc->data.cgrade); printf("\n\npress?any?key?to?return"); getchar(); } /*利用插入排序法實現單鏈表的按總分字段的降序排序,從高到低*/ void?Sort(Link?l) { Link?ll; Node?*p,*rr,*s; int?i=0; if(l->next==NULL) {?system("cls"); printf("\n=====>Not?student?record!\n"); getchar(); return?; } ll=(Node*)malloc(sizeof(Node));?/*用于創建新的節點*/ if(!ll) { printf("\n?allocate?memory?failure?");?/*如沒有申請到,打印提示信息*/ return?;?????????????/*返回主界面*/ } ll->next=NULL; system("cls"); Disp(l);??/*顯示排序前的所有學生記錄*/ p=l->next; while(p)?/*p!=NULL*/ { s=(Node*)malloc(sizeof(Node));?/*新建節點用于保存從原鏈表中取出的節點信息*/ if(!s)?/*s==NULL*/ { printf("\n?allocate?memory?failure?");?/*如沒有申請到,打印提示信息*/ return?;?????????????/*返回主界面*/ } s->data=p->data;?/*填數據域*/ s->next=NULL;????/*指針域為空*/ rr=ll; /*rr鏈表于存儲插入單個節點后保持排序的鏈表,ll是這個鏈表的頭指針,每次從頭開始查找插入位置*/ while(rr->next!=NULL?&&?rr->next->data.total>=p->data.total) {rr=rr->next;}?/*指針移至總分比p所指的節點的總分小的節點位置*/ if(rr->next==NULL)/*若新鏈表ll中的所有節點的總分值都比p->data.total大時,就將p所指節點加入鏈表尾部*/ rr->next=s; else?/*否則將該節點插入至第一個總分字段比它小的節點的前面*/ { s->next=rr->next; rr->next=s; } p=p->next;?/*原鏈表中的指針下移一個節點*/ } l->next=ll->next;?/*ll中存儲是的已排序的鏈表的頭指針*/ p=l->next;???????????/*已排好序的頭指針賦給p,準備填寫名次*/ while(p!=NULL)??/*當p不為空時,進行下列操作*/ { i++;???????/*結點序號*/ p->data.mingci=i;???/*將名次賦值*/ p=p->next;???/*指針后移*/ } Disp(l); saveflag=1; printf("\n????=====>sort?complete!\n"); } /*數據存盤,若用戶沒有專門進行此操作且對數據有修改,在退出系統時,?會提示用戶存盤*/ void?Save(Link?l) { FILE*?fp; Node?*p; int?count=0; fp=fopen("c:\student","wb");/*以只寫方式打開二進制文件*/ if(fp==NULL)?/*打開文件失敗*/ { printf("\n=====>open?file?error!\n"); getchar(); return?; } p=l->next; while(p) { if(fwrite(p,sizeof(Node),1,fp)==1)/*每次寫一條記錄或一個節點信息至文件*/ { p=p->next; count++; } else { break; } } if(count>0) { getchar(); printf("\n\n\n\n\n=====>save?file?complete,total?saved's?record?number?is:%d\n",count); getchar(); saveflag=0; } else {system("cls"); printf("the?current?link?is?empty,no?student?record?is?saved!\n"); getchar(); } fclose(fp);?/*關閉此文件*/ } void?main() { Link?l;??????/*定義鏈表*/ FILE?*fp;????/*文件指針*/ int?select;?????/*保存選擇結果變量*/ char?ch;?????/*保存(y,Y,n,N)*/ int?count=0;?/*保存文件中的記錄條數(或結點個數)*/ Node?*p,*r;???/*定義記錄指針變量*/ l=(Node*)malloc(sizeof(Node)); if(!l) { printf("\n?allocate?memory?failure?");?/*如沒有申請到,打印提示信息*/ return?;?????????????/*返回主界面*/ } l->next=NULL; r=l; fp=fopen("C:\\student","ab+");?/*以追加方式打開一個二進制文件,可讀可寫,若此文件不存在,會創建此文件*/ if(fp==NULL) { printf("\n=====>can?not?open?file!\n"); exit(0); } while(!feof(fp)) { p=(Node*)malloc(sizeof(Node)); if(!p) { printf("?memory?malloc?failure!\n");????/*沒有申請成功*/ exit(0);???????/*退出*/ } if(fread(p,sizeof(Node),1,fp)==1)?/*一次從文件中讀取一條學生成績記錄*/ { p->next=NULL; r->next=p; r=p;????????????????????????????/*r指針向后移一個位置*/ count++; } } fclose(fp);?/*關閉文件*/ printf("\n=====>open?file?sucess,the?total?records?number?is?:?%d.\n",count); menu(); while(1) { system("cls"); menu(); p=r; printf("\n??????????????Please?Enter?your?choice(0~9):");????/*顯示提示信息*/ scanf("%d",&select); if(select==0) { if(saveflag==1)?/*若對鏈表的數據有修改且未進行存盤操作,則此標志為1*/ {?getchar(); printf("\n=====>Whether?save?the?modified?record?to?file?(y/n):"); scanf("%c",&ch); if(ch=='y'||ch=='Y') Save(l); } printf("=====>thank?you?for?useness!"); getchar(); break; } switch(select) { case?1:Add(l);break;????????????/*增加學生記錄*/ case?2:Del(l);break;???????????/*刪除學生記錄*/ case?3:Qur(l);break;???????????/*查詢學生記錄*/ case?4:Modify(l);break;????????/*修改學生記錄*/ case?5:Insert(l);break;????????/*插入學生記錄*/ case?6:Tongji(l);break;???????/*統計學生記錄*/ case?7:Sort(l);break;????????/*排序學生記錄*/ case?8:Save(l);break;????????/*保存學生記錄*/ case?9:system("cls");Disp(l);break;?????????/*顯示學生記錄*/ default:?Wrong();getchar();break;????????/*按鍵有誤,必須為數值0-9*/ } } } C 語言 數據結構 項目管理 ProjectMan
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。