基於動態鏈表的學生成績管理系統

摘要

學生綜合利用本學期所學完成了學生成績管理系統的編寫,利用預處理、數據類型、自定義函數、結構體、鏈表、文件操作、Windows.h中某些處理等知識,在VS2012中對學生成績管理系統進行編寫,初步實現了管理員模式、來賓模式下的輸入、刪除、查詢、修改、排序、保存、切換登陸模式、修改管理員信息、退出等功能,並且在刪除、查詢功能中實現按照學號或姓名操作,排序功能中實現按照學號、姓名、五門課成績、總分進行由大到小或由小到大的排序。同時,本學生成績管理系統初步解決了由於輸入錯誤造成的嚴重後果,又以藍底黃字及區域化佈局的友好界面展示在使用者眼前。

撰寫順序

 由於學生將本實驗在完成實驗任務的基礎上做成了功能較爲完整的學生信息管理系統,但考慮到代碼較長(1357行),故學生通過先展示成果後附加代碼的形式進行實驗分析。

成果展示

圖1  創建系統管理員

圖一程序開始訪問admin.txt文件,若無賬號密碼信息,則創建系統管理員,並將賬號密碼信息保存於admin.txt中。

圖2 選擇登陸方式


圖2展示已經有管理員信息的情況下選擇登陸方式,當輸入賬號密碼時,與admin.txt中的信息匹配,若正確允許進入,錯誤,提示錯誤後,重新選擇登錄方式。

圖3 管理員菜單界面


圖3爲管理員菜單界面,0-11分別完成相應的操作。輸入錯誤顯示錯誤,重新輸入。

圖4 學生信息輸入


圖4爲無學生記錄情況下的學生信息輸入。

圖5 學生信息再輸入


圖4爲有學生記錄情況下的學生信息輸入。依次要求輸入學號、姓名、5門科成績。且學科成績要求整數(依據實際情況設計),若輸入錯誤,提示錯誤,重新輸入直至正確。

圖6 學生信息刪除


圖6爲有學生記錄時學生信息刪除,按照學號或姓名兩種方式刪除。若無學生記錄,提示無學生記錄,無法刪除。

圖7 學生成績查詢


圖7爲有學生記錄時學生成績查詢,通過學號或姓名進行查詢。若無學生記錄,提示無學生記錄,不提供查詢。

圖8 學生信息修改


  圖8爲有學生記錄時學生信息修改,按照學號進行修改其他內容。若無學生記錄,提示無學生記錄,不提供修改。

圖9 排序菜單


圖9爲排序菜單,0-14分別提供如上內容。

圖10排序


圖10爲選擇排序菜單中“4”時的排序結果。一旦進行排序,數據將保存於stu-sort.c中,而不改變原文件stu.c。

圖11 保存記錄


圖11爲有新數據寫入時保存記錄後的界面(因爲圖4後的操作,故有5名學生記錄)。若無新數據寫入,保存失敗。

圖12  顯示不及格學生


圖12爲顯示不及格學生具體信息及不及格同學總人數。

圖13  顯示優秀學生


圖13爲顯示優秀學生具體信息及總人數。

圖14 修改管理員信息


圖14爲修改管理員信息,管理員信息同樣保存在admin.txt中。

圖15 來賓菜單界面


圖15爲登陸方式選擇“0”時,來賓菜單界面,0-6分別完成具體操作。

圖16 退出系統若有數據未保存詢問是否保存


圖16 退出系統若有數據未保存詢問是否保存,選擇後退出整個程序。


【附件】

[源程序]

#include <stdio.h>#include <string.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define HEADER2 "  **********************************************************************\n  *     學號     姓名  學科1  學科2  學科3  學科4  學科5  總分   平均  *\n  **********************************************************************\n"
#define FORMAT  "  * %8s  %7s  %5d  %5d  %5d  %5d  %5d %5d  %.2f  *\n  **********************************************************************\n"
#define DATA  p->data.num,p->data.name,p->data.grade[0],p->data.grade[1],p->data.grade[2],p->data.grade[3],p->data.grade[4],p->data.total,p->data.ave
int saveflag=0; /*是否需要存盤的標誌變量*/
int sortflag=0; /*是是否已經排序的標誌變量*/
time_t now;/*系統時間*/
struct student {
    char num[20];   /*學號*/
    char name[15]; /*姓名*/
    int grade[5];     /*學科成績*/
    int total;      /*總分*/
    float ave;      /*平均分*/
};
typedef struct node{     //定義每條記錄或結點的數據結構
    struct student data; /*數據域*/
    struct node *next;    /*指針域*/
}Node,*Link;   /*Node爲node類型的結構變量,*Link爲node類型的指針變量*/
void menu() {
    now = time (NULL);
    printf("                          學生成績管理系統 \n");
    printf("\n");
    printf("     *************************************************************\n");
    printf("     *                                                           *\n");
    printf("     *          1 輸入成績                 2 刪除成績            *\n");
    printf("     *                                                           *\n");
    printf("     *          3 查詢成績                 4 修改成績            *\n");
    printf("     *                                                           *\n");
    printf("     *          5 排序成績                 6 保存記錄            *\n");
    printf("     *                                                           *\n");
    printf("     *          7 不及格學生               8 優秀學生            *\n");
    printf("     *                                                           *\n");
    printf("     *          9 顯示所有                 0 退出系統            *\n");
    printf("     *                                                           *\n");
    printf("     *************************************************************\n");
    printf("     *          10 切換登錄模式            11 修改管理員信息     *\n");
    printf("     *************************************************************\n");
    printf("       Made by ChengXiang, now time is %s\n",ctime(&now));
    printf("\n     *************************************************************\n");
    printf("     *          請您選擇操作命令(0~11):");    /*顯示提示信息*/
}
void menu2(){
    now = time (NULL);
    system("cls");          //清屏
    printf("\n                                                                  來賓模式\n\n\n");
    printf("                          學生成績管理系統 \n");
    printf("\n");
    printf("     *************************************************************\n");
    printf("     *                                                           *\n");
    printf("     *          1 查詢成績                 2 排序成績            *\n");
	printf("     *                                                           *\n");
    printf("     *          3 不及格學生               4 優秀學生            *\n");
    printf("     *                                                           *\n");
    printf("     *          5 顯示所有                 0 退出系統            *\n");
    printf("     *                                                           *\n");
    printf("     *************************************************************\n");
    printf("     *          6 切換登錄模式                                   *\n");
    printf("     *************************************************************\n");
    printf("       Made by ChengXiang, now time is %s\n",ctime(&now));
    printf("\n     *************************************************************\n");
    printf("     *          請您選擇操作命令(0~6):");    /*顯示提示信息*/
}
void sortmenu(){   
	now = time (NULL);
    system("cls");          //清屏
    printf("\n                             學生成績管理系統 \n");
    printf("\n");
    printf("     ****************************排序菜單*************************\n");
    printf("     *                                                           *\n");
    printf("     *          1  按學號從小到大         2  按學號從大到小      *\n");
	printf("     *                                                           *\n");
    printf("     *          3  按總分從小到大         4  按總分從大到小      *\n");
    printf("     *                                                           *\n");
    printf("     *          5  按學科1從小到大        6  按學科1從大到小     *\n");
    printf("     *                                                           *\n");
    printf("     *          7  按學科2從小到大        8  按學科2從大到小     *\n");
    printf("     *                                                           *\n");
    printf("     *          9  按學科3從小到大        10 按學科3從大到小     *\n");
    printf("     *                                                           *\n");
    printf("     *          11 按學科4從小到大        12 按學科4從大到小     *\n");
    printf("     *                                                           *\n");
    printf("     *          13 按學科5從小到大        14 按學科5從大到小     *\n");
    printf("     *                                                           *\n");
	printf("     *          0  按姓名字典序排序                              *\n");
    printf("     *************************************************************\n");
    printf("       Made by ChengXiang, now time is %s\n",ctime(&now));
    printf("\n     *************************************************************\n");
    printf("     *          請您選擇操作命令(0~14):");    /*顯示提示信息*/
}
void printheader(){
    printf(HEADER2);
} /*格式化輸出表頭*/
void printdata(Node *pp) {
    Node* p;
    p=pp;
    printf(FORMAT,DATA);
}/*格式化輸出表中數據*/
void Wrong() {  
    printf("\n");
    printf("     *************************************************************\n");
	printf("     *                    錯誤:輸入不合法!!!                     *\n");
    printf("     *************************************************************\n");
    getch();
}/*輸出按鍵錯誤信息*/
void Nofind(){ /*輸出未查找此學生的信息*/
    printf("\n");
    printf("     *************************************************************\n");
	printf("     *                      沒有該學生!!!                        *\n");
    printf("     *************************************************************\n");
}
void Disp(Link l){ /*顯示單鏈表l中存儲的學生記錄,內容爲student結構中定義的內容*/
    system("cls");          //清屏
    Node *p;
    p=l->next; /*l存儲的是單鏈表中頭結點的指針,該頭結點沒有存儲學生信息,指針域指向的後繼結點纔有學生信息*/
    printf("\n                          學生成績管理系統 \n");
    if(!p) /*p==NULL,NUll在stdlib中定義爲0*/
    {
		printf("     ***************************學生記錄**************************\n");
		printf("     *                         無學生記錄!                      *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("      Made by ChengXiang, now time is %s\n",ctime(&now));
        getchar();
        return;
    }
    printheader(); /*輸出表格頭部*/
    while(p)    /*逐條輸出鏈表中存儲的學生信息*/
    {
        printdata(p);
        p=p->next; /*移動直下一個結點*/
    }
	now = time (NULL);
	printf("        Made by ChengXiang, now time is %s\n",ctime(&now));
}
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 failStu(Link l)
{
	Node *r;
	int q,sum=0;
	system("cls");
	now = time (NULL);
    printf("\n                          學生成績管理系統 \n");
	printheader();
	r=l->next;
	while(r)
	{
		int i;
		q=0;
		for(i=0;i<5;i++)
			if(r->data.grade[i]<60)
			{
				q=1;
				break;
			}
		if(q)
		{
			printdata(r);
		}
		sum+=q;
		r=r->next;
	}
	if(sum)
		printf("  *                           共有%d名學生不及格                        *\n",sum);
	else
		printf("  *                           good,沒有同學不及格                       *\n",sum);
    printf("  **********************************************************************\n");
	printf("           Made by ChengXiang, now time is %s\n",ctime(&now));
	getchar();
	getchar();
}
void prefectStu(Link l)
{
	Node *r;
	int q,sum=0;
	system("cls");
	now = time (NULL);
    printf("\n                          學生成績管理系統 \n");
	printheader();
	r=l->next;
	while(r)
	{
		int i;
		q=0;
		for(i=0;i<5;i++)
			if(r->data.grade[i]>=90)
			{
				q=1;
				break;
			}
		if(q)
		{
			printdata(r);
		}
		sum+=q;
		r=r->next;
	}
	if(sum)
		printf("  *                            共有%d名學生優秀                         *\n",sum);
	else
		printf("  *                          poor,沒有同學是優秀的                      *\n",sum);
    printf("  **********************************************************************\n");
	printf("           Made by ChengXiang, now time is %s\n",ctime(&now));
	getchar();
	getchar();
}
void stringinput(char *t,int lens,char *notice){/*輸入字符串信息*/
   char n[255];
   do
   {
       printf(notice); /*顯示提示信息*/
       scanf("%s",n); /*輸入字符串*/
       if(strlen(n)>lens) /*進行長度校驗,超過lens值重新輸入*/
	   {   
			printf("\n");
			printf("     *************************************************************\n");
			printf("     *                        超出長度!!!                        *\n");
			printf("     *************************************************************\n");
	   }
   }while(strlen(n)>lens);
   strcpy(t,n); /*將輸入的字符串拷貝到字符串t中*/
}
int numberinput(char *notice){/*輸入分數信息*/
    int t=0;
    do
    {
        printf(notice); /*顯示提示信息*/
        scanf("%d",&t); /*輸入分數*/
        if(t>100 || t<0) //分數校驗
		{
			printf("\n");
			printf("     *************************************************************\n");
			printf("     *                   分數必須在0~100之間!!!                  *\n");
			printf("     *************************************************************\n");
		}
    }while(t>100 || t<0);
    return t;
}
void Add(Link l){/*在表尾添加學生信息*/
    Node *p,*r,*s;
	int i;
    char ch,flag=0,num[10];
    r=l;
    system("cls");
    Disp(l); /*先打印出已有的學生信息*/
    while(r->next!=NULL)
        r=r->next; /*將指針移至於鏈表最末尾,準備添加記錄*/
    while(1) /*一次可輸入多條記錄,直至輸入學號爲0的記錄結點添加操作*/
    {
        s=l->next;
        while(1)
        {
			printf(" **********************************************************************\n");
            stringinput(num,10,"  *    學號(按0退出):"); /*格式化輸入學號並檢驗*/
            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("  **********************************************************************\n");
                printf("  *    學號%s已存在,是否重新輸入?(y/n)\a",num);
                scanf("%c",&ch);
                if(ch=='y'||ch=='Y')
                    continue;
                else
                    return ;
            }
            else
                break;
        }
        p=(Node *)malloc(sizeof(Node));
        strcpy(p->data.num,num); /*將字符串num拷貝到p->data.num中*/
		printf("  **********************************************************************\n");
        stringinput(p->data.name,15,"  *    Name:");
		printf("  **********************************************************************\n");
        p->data.grade[0]=numberinput("  *    學科1[0-100]:");
		printf("  **********************************************************************\n");
        p->data.grade[1]=numberinput("  *    學科2[0-100]:");
		printf("  **********************************************************************\n");
        p->data.grade[2]=numberinput("  *    學科3[0-100]:");
		printf("  **********************************************************************\n");
        p->data.grade[3]=numberinput("  *    學科4[0-100]:");
		printf("  **********************************************************************\n");
        p->data.grade[4]=numberinput("  *    學科5[0-100]:");
		printf("  **********************************************************************\n");
		for(i=0,p->data.total=0;i<5;i++)
			p->data.total+=p->data.grade[i]; /*計算總分*/
        p->data.ave=(float)(p->data.total*1.0/5); /*計算平均分*/
        p->next=NULL;
        while(r->next!=NULL)
            r=r->next;
        r->next=p;
        saveflag=1;
    }
}
void Qur(Link l){ /*按學號或姓名,查詢學生記錄*/
    system("cls");
    int select; /*1:按學號查,2:按姓名查,其他:返回主界面(菜單)*/
    char searchinput[20]; /*保存用戶輸入的查詢內容*/
    Node *p;	
    if(!l->next) /*若鏈表爲空*/
    {	
		printf("\n                             學生成績管理系統 \n\n");
		printf("     ***************************查詢成績**************************\n");
		printf("     *                    暫無學生記錄,查詢失敗                  *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("      Made by ChengXiang, now time is %s\n",ctime(&now));
		getchar();
		getchar();
        return;
    }
	printf("\n                             學生成績管理系統 \n\n");
	printf("     ***************************查詢成績**************************\n");
    printf("     *                                                           *\n");
	printf("     *           1 通過學號查找            2 通過姓名查找        *\n");
    printf("     *                                                           *\n");
	printf("     *************************************************************\n");
	now = time (NULL);
	printf("      Made by ChengXiang, now time is %s\n",ctime(&now));
	printf("\n");
	printf("     *************************************************************\n");
    printf("     *           請選擇[1,2]:");
    scanf("%d",&select);
    if(select==1)   /*按學號查詢*/
    {
        stringinput(searchinput,10,"     *           請輸入要查找的學號:");
        p=Locate(l,searchinput,"num");/*在l中查找學號爲searchinput值的節點,並返回節點的指針*/
        if(p) /*若p!=NULL*/
        {
            printheader();
            printdata(p);
			printf("     *************************************************************\n");
        }
        else
            Nofind();
    }
    else if(select==2) /*按姓名查詢*/
    {
        stringinput(searchinput,15,"     *           請輸入學生姓名:");
        p=Locate(l,searchinput,"name");
        if(p)
        {
            printheader();
            printdata(p);
			printf("     *************************************************************\n");
        }
        else
            Nofind();
    }
    else
        Wrong();
    system("PAUSE");
}
void Del(Link l){//刪除學生記錄:先找到保存該學生記錄的節點,然後刪除該節點
    int sel;
    Node *p,*r;
    char findmess[20];
    if(!l->next)
    {
        system("cls");
		printf("\n");
		printf("                          學生成績管理系統 \n");
		printf("\n");
		printf("     *************************************************************\n");
        printf("     *                      暫無學生記錄!!!                      *\n");
		printf("     *************************************************************\n");
        getch();
        return;
    }
    system("cls");
    Disp(l);
	printf("     *************************************************************\n");
    printf("     *              1 通過學號刪除       2 通過姓名刪除          *\n");
    printf("     *              請選擇[1,2]:");
    scanf("%d",&sel);
    if(sel==1)
    {
        stringinput(findmess,10,"     *              請輸入學號:");
        p=Locate(l,findmess,"num");
        if(p)
        {
            r=l;
            while(r->next!=p)
            r=r->next;
            r->next=p->next;
            free(p); /*釋放內存空間*/
			printf("     *************************************************************\n");
			printf("     *                          刪除成功!!!                      *\n");
			printf("     *************************************************************\n");
            saveflag=1;
        }
        else
            Nofind();
    }
    else if(sel==2) /*先按姓名查詢到該記錄所在的節點*/
    {
        stringinput(findmess,15,"     *              請輸入學生姓名:");
        p=Locate(l,findmess,"name");
        if(p)
        {
            r=l;
            while(r->next!=p)
            r=r->next;
            r->next=p->next;
            free(p);
			printf("     *************************************************************\n");
			printf("     *                          刪除成功!!!                      *\n");
			printf("     *************************************************************\n");
            saveflag=1;
        }
        else
        Nofind();
    }
    else
        Wrong();
    getchar();
}
void Modify(Link l){//修改學生記錄.先按輸入的學號查詢到該記錄,然後提示用戶修改學號之外的值,學號不能修改
    Node *p;
	int i;
    char findmess[20];
    if(!l->next)
    {
        system("cls");
		printf("\n                          學生成績管理系統 \n\n");
		printf("     *************************************************************\n");
        printf("     *                        沒有學生記錄!!!                    *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("       Made by ChengXiang, now time is %s\n",ctime(&now));
        getchar();
        getchar();
        return;
    }
    system("cls");
    printf("修改學生記錄");
    Disp(l);
	printf(" **********************************************************************\n");
    stringinput(findmess,10,"  *            請輸入學號:"); /*輸入並檢驗該學號*/
	printf("  **********************************************************************\n");
    p=Locate(l,findmess,"num"); /*查詢到該節點*/
    if(p) /*若p!=NULL,表明已經找到該節點*/
    {
        printf("  *            學號:%s\n",p->data.num);
        printf("  *            姓名:%s                                                  *\n",p->data.name);
        stringinput(p->data.name,15,"  *            輸入新姓名:");
        printf("  *            學科1:%d                                                *\n",p->data.grade[0]);
        p->data.grade[0]=numberinput("  *            學科1[0-100]:");
        printf("  *            學科2:%d                                                *\n",p->data.grade[1]);
        p->data.grade[1]=numberinput("  *            學科2[0-100]:");
        printf("  *            學科3:%d                                                *\n",p->data.grade[2]);
        p->data.grade[2]=numberinput("  *            學科3[0-100]:");
        printf("  *            學科4:%d                                                *\n",p->data.grade[3]);
        p->data.grade[3]=numberinput("  *            學科4[0-100]:");
        printf("  *            學科5:%d                                                *\n",p->data.grade[4]);
        p->data.grade[4]=numberinput("  *            學科5[0-100]:");
		for(i=0,p->data.total=0;i<5;i++)
			p->data.total+=p->data.grade[i]; /*計算總分*/
        p->data.ave=(float)(p->data.total*1.0/5);
		printf("  **********************************************************************\n");
        printf("  *                              修改成功!!!                           *\n");
		printf("  **********************************************************************\n%");
		getchar();
        saveflag=1;
    }
    else
        Nofind();
    getchar();
}
void Sort(Link l){
    system("cls");		
    Link ll;
    Node *p,*rr,*s;
    int i=0,select;
    if(l->next==NULL)
    {
	    printf("\n                          學生成績管理系統 \n");
		printf("     *************************************************************\n");
        printf("     *            暫無學生記錄!請輸入學生記錄後再進行排序        *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("           Made by ChengXiang, now time is %s\n",ctime(&now));
        getchar();
		getchar();
		return ;
    }  
	sortmenu();
	scanf("%d",&select);
    printf("     *************************************************************\n");
	switch(select)
    {
    case 1:/*按學號從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.num<p->data.num)
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}
	case 2:/*按學號從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.num>=p->data.num)
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}


	case 3:/*按總分從小到大*/
		{			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.total<p->data.total)
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}


	case 4:/*按總分從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); /*用於創建新的節點*/
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l); /*顯示排序前的所有學生記錄*/
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node)); /*新建節點用於保存從原鏈表中取出的節點信息*/
				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=p->next;   /*指針後移*/
			}
			break;
		}


	case 5:/*按學科1從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[0]<p->data.grade[0])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}
	case 6:/*按學科1從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[0]>=p->data.grade[0])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}
	case 7:/*按學科2從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[1]<p->data.grade[1])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}


	case 8:/*按學科2從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[1]>=p->data.grade[1])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}


	case 9:/*按學科3從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[2]<p->data.grade[2])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}


	case 10:/*按學科3從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[2]>=p->data.grade[2])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}


	case 11:/*按學科4從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[3]<p->data.grade[3])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}
	case 12:/*/*按學科4從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[3]>=p->data.grade[3])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;            /*增加學生記錄*/
		}
	case 13:/*按學科5從小到大*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[4]<p->data.grade[4])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}
	case 14:/*按學科5從大到小*/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node)); 
				s->data=p->data;
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.grade[4]>=p->data.grade[4])
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next;
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}
	case 0:/**/
		{
			ll=(Node*)malloc(sizeof(Node)); 
			ll->next=NULL;
			printf("當前狀態:\n");
		  //  puts("錯誤不在這!");
			Disp(l);
		  //  system("PAUSE");
			p=l->next;
			while(p) /*p!=NULL*/
			{
				s=(Node*)malloc(sizeof(Node));
				s->data=p->data; 
				s->next=NULL;
				rr=ll;
				while(rr->next!=NULL && rr->next->data.name>=p->data.name)
				{
					rr=rr->next;
				} 
				if(rr->next==NULL)
					rr->next=s;
				else 
				{
					s->next=rr->next;
					rr->next=s;
				}
				p=p->next;
			}
			l->next=ll->next; 
			p=l->next;
			while(p!=NULL) 
			{
				i++;
				p=p->next;
			}
			break;
		}
        default: Wrong();getch();break;        /*按鍵有誤,必須爲數值0-9*/
    }
    printf("\n*********************************************\n");
//  puts("錯誤不在這!");
    Disp(l);
    saveflag=1;
	printf(" **********************************************************************\n");
    printf("  *                          排序完成!!!                               *\n");
	printf("  **********************************************************************\n");
	sortflag=1;
    system("PAUSE");
}
void Save(Link l){   //數據存盤,若用戶沒有專門進行此操作且對數據有修改,在退出系統時,會提示用戶存盤
    FILE* fp1, *fp2;
    Node *p;
    int count=0;
    fp1=fopen("stu.c","w+");/*以只寫方式打開二進制文件*/
    fp2=fopen("stu-sort.c","w+");/*以只寫方式打開二進制文件*/
    if(sortflag==0)
	{
		p=l->next;
		while(p)
		{
			if(fwrite(p,sizeof(Node),1,fp1)==1)
			{
				p=p->next;
				count++;
			}
			else break;
		}
		if(count>0)
		{
			printf("\n\n\n\n\n");
			printf("     *************************************************************\n");
			printf("     *                 保存完畢,當前有%d名學生記錄              *\n",count);
			printf("     *************************************************************\n");
			saveflag=0;
		}
		else
			printf("空文件,保存失敗!!\n");
		fclose(fp1); //關閉此文件
		getch();
	}
	else
	{
		    p=l->next;
		while(p)
		{
			if(fwrite(p,sizeof(Node),1,fp2)==1)
			{
				p=p->next;
				count++;
			}
			else break;
		}
		if(count>0)
		{
			printf("\n\n\n\n\n        保存完畢,當前有%d名學生記錄\n",count);
			saveflag=0;
		}
		else
			printf("空文件,保存失敗!!\n");
		fclose(fp2); //關閉此文件
		getch();
		sortflag=0;
	}
}
int login(){
    FILE *fp1,*fp2;
    int state;
    char str1[20],str2[20],str_z[20],str_m[20];		
    if((fp1=fopen("admin.txt","rb"))==NULL)
    {
		printf("\n                             學生成績管理系統 \n\n");
		printf("     *************************創建管理員賬號**********************\n");
		printf("     *                    本系統無管理員,請創建!               *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("      Made by ChengXiang, now time is %s\n",ctime(&now));
		printf("     *************************************************************\n");
        printf("     *              請輸入管理員賬號:");
        scanf("%s",str_z);
        printf("     *              請輸入密碼:      ");
        scanf("%s",str_m);
		printf("     *************************************************************\n");
        fp2=fopen("admin.txt","wb");
        fprintf(fp2,"%s%c",str_z,'\n');
        fprintf(fp2,"%s%c",str_m,' ');
        fclose(fp2);
    }
    fp1=fopen("admin.txt","rb");
    fscanf(fp1,"%s",str1);
    fscanf(fp1,"%s",str2);
    fclose(fp1);
    while(1)
    {
		system("cls");
		printf("\n                             學生成績管理系統 \n\n");
		printf("     ****************************登錄方式*************************\n");
		printf("     *                                                           *\n");
        printf("     *              1.管理員模式          0.來賓模式             *\n");
		printf("     *                                                           *\n");
		printf("     *************************************************************\n");
		now = time (NULL);
		printf("      Made by ChengXiang, now time is %s\n",ctime(&now));
		printf("     *************************************************************\n");
        printf("     *              請你選擇(0-1):");
        scanf("%d",&state);
		printf("     *************************************************************\n");
        if(state==0)
            return 0;
        else if(state==1)
        {
			printf("\n     *************************************************************\n");
			printf("     *              請輸入賬號:");
            scanf("%s",str_z);
			printf("     *              請輸入密碼:");
            scanf("%s",str_m);
			printf("     *************************************************************\n");
            if(strcmp(str1,str_z)==0&&strcmp(str2,str_m)==0)
			{
				getchar();
				getchar();
                return 1;
			}
            else
            {
				printf("     *************************************************************\n");
                printf("     *                     賬號或密碼錯誤!!!                     *\n");
				printf("     *************************************************************\n");
                system("PAUSE");
                system("cls");
            }
        }
        else
        {				
			printf("     *************************************************************\n");
			printf("     *                        輸入不合法!!!                      *\a \n");
			printf("     *************************************************************\n");
            system("PAUSE");
            system("cls");
        }
    }
}
void Modify_admin(){
    FILE *fp;
    char str_z[20],str_m[20];
    fp=fopen("admin.txt","wb");
	printf("     *************************************************************\n");
	printf("     *          請輸入管理員賬號:");
    scanf("%s",str_z);
	printf("     *          請輸入密碼:      ");
    scanf("%s",str_m);
	printf("     *************************************************************\n");
    fprintf(fp,"%s%c",str_z,'\n');
    fprintf(fp,"%s%c",str_m,' ');
    fclose(fp);
	printf("\n     *************************************************************\n");
    printf("     *                  管理員信息更新完畢!!!                   *\a\n");
	printf("     *************************************************************\n");
    getch();
}
int main(){
    system("color 9e");//主屏函數黃色
    Link L;      /*定義鏈表*/
    FILE *fp,*fp1;    /*文件指針*/
    int select,State=0;  /*保存選擇結果變量*/
    char ch,admin[20],admin_p[20];     /*保存(y,Y,n,N)*/
    int count=0; /*保存文件中的記錄條數(或結點個數)*/
    Node *p,*r;  /*定義記錄指針變量*/
    L=(Node*)malloc(sizeof(Node));
    L->next=NULL;
    r=L;
    fp=fopen("stu.c","ab+");
    fp1=fopen("stu-sort.c","ab+");
    Loop:{
        State=login();
    }
    while(!feof(fp))
    {
        p=(Node*)malloc(sizeof(Node));
        if(fread(p,sizeof(Node),1,fp)==1) /*一次從文件中讀取一條學生成績記錄*/
        {
            p->next=NULL;
            r->next=p;
            r=p;                            /*r指針向後移一個位置*/
            count++;
        }
    }
    fclose(fp); /*關閉文件*/
    if(State==1)
    {
    while(1)
    {
        system("cls");
        printf("\n                                                                  管理員模式\n\n\n");
        menu();
        p=r;
        scanf("%d",&select);
		printf("     *************************************************************\n");
        if(select==0)
        {
            if(saveflag==1) /*若對鏈表的數據有修改且未進行存盤操作,則此標誌爲1*/
            {
                getchar();
				printf("     *************************************************************\n");
                printf("     *           記錄已修改,是否保存當前記錄?(y/n):");
                scanf("%c",&ch);
				printf("     *************************************************************\n");
                if(ch=='y'||ch=='Y')
                    Save(L);
            }
			printf("     *************************************************************\n");
            printf("     *                         謝謝您的使用!!!                   *\n");
			printf("     *************************************************************\n");
            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:Sort(L);break;        /*排序學生記錄*/
        case 6:Save(L);break;        /*保存學生記錄*/
        case 7:failStu(L);break;        /*不及格學生記錄*/
        case 8:prefectStu(L);break;        /*優秀學生記錄*/
        case 9:Disp(L);system("PAUSE");break;         /*顯示學生記錄*/
        case 10:system("cls");goto Loop;
        case 11:Modify_admin();break;
        default: Wrong();getch();break;        /*按鍵有誤,必須爲數值0-9*/
        }
    }
    }
    else
    {
        while(1)
        {
            system("cls");
			now = time (NULL);
			printf("           Made by ChengXiang, now time is %s\n",ctime(&now));
            menu2();
            scanf("%d",&select);
		printf("     *************************************************************\n");
            if(select==0)
            {
				printf("     *************************************************************\n");
				printf("     *                         謝謝您的使用!!!                   *\n");
				printf("     *************************************************************\n");
                exit(1);
            }
            switch(select)
            {
                case 1:Qur(L);break;           /*查詢學生記錄*/
                case 2:Sort(L);break;        /*排序學生記錄*/
				case 3:failStu(L);break;        /*不及格學生記錄*/
				case 4:prefectStu(L);break;        /*優秀學生記錄*/
                case 5:Disp(L);system("PAUSE");break;         /*顯示學生記錄*/
                case 6:system("cls");goto Loop;
                default: Wrong();getch();break;        /*按鍵有誤,必須爲數值0-9*/
            }
        }
    }
    return 0;
}

下面分別對上述知識進行總結,以幫助今後的進一步學習。

預處理:

預處理功能主要包括宏定義,文件包含,條件編譯三部分。分別對應宏定義命令,文件包含命令,條件編譯命令三部分實現。

  預處理過程讀入源代碼,檢查包含預處理指令的語句和宏定義,並對源代碼進行響應的轉換。預處理過程還會刪除程序中的註釋和多餘的空白字符。

預處理指令是以#號開頭的代碼行。#號必須是該行除了任何空白字符外的第一個字符。#後是指令關鍵字,在關鍵字和#號之間允許存在任意個數的空白字符。整行語句構成了一條預處理指令,該指令將在編譯器進行編譯之前對源代碼做某些轉換。

數據類型:

自定義函數:

C源程序是由函數組成的。雖然在C語言入門系列前面幾篇的程序中大都只有一個主函數main(),但實用程序往往由多個函數組成。函數是C源程序的基本模塊,通過對函數模塊的調用實現特定的功能。C語言中的函數相當於其它高級語言的子程序。C語言不僅提供了極爲豐富的庫函數,還允許用戶建立自己定義的函數。用戶可把自己的算法編成一個個相對獨立的函數模塊,然後用調用的方法來使用函數。可以說C程序的全部工作都是由各式各樣的函數完成的,所以也把C語言稱爲函數式語言。

 由於採用了函數模塊式的結構,C語言易於實現結構化程序設計。使程序的層次結構清晰,便於程序的編寫、閱讀、調試。


結構體:

C語言中,結構體是一種很常用的數據類型。簡單而又複雜,能夠用好它實屬不易。下面總結下它的常見用法及容易出錯的地方。
鏈表:

C語言中,結構體是一種很常用的數據類型。簡單而又複雜,能夠用好它實屬不易。下面總結下它的常見用法及容易出錯的地方。
文件操作:
文件的基本概念
  所謂“文件”是指一組相關數據的有序集合。 這個數據集有一個名稱,叫做文件名。 實際上在前面的各章中我們已經多次使用了文件,例如源程序文件、目標文件、可執行文件、庫文件 (頭文件)等。文件通常是駐留在外部介質(如磁盤等)上的, 在使用時才調入內存中來。從不同的角度可對文件作不同的分類。從用戶的角度看,文件可分爲普通文件和設備文件兩種。

聲明:以上詳情均可見網站鏈接。


發佈了31 篇原創文章 · 獲贊 21 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章