1. 程式人生 > >C語言編寫學生成績管理系統

C語言編寫學生成績管理系統

        這個《學生成績管理系統》是以前大一的時候的課設,今天整理檔案的時候發現了,就直接把程式碼貼到部落格上吧。挺基礎的一個東西,就是涉及到C語言實現的連結串列,以及檔案操作,結構體的序列化儲存與讀取等。

DataType.h

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#ifndef ___DDATA_TYPE__
#define ___DDATA_TYPE__


typedef struct grades					//成績
{
	char  id[20];						//學號
	char subject[20];					//科目
	float grade;						//成績
}Grade;

typedef struct GradeDataNode			//成績節點
{
	Grade grades;   
	struct GradeDataNode *Pnext;

}GradeData;


typedef struct studentInformation		//學生資訊
{
	char Class[30];						//班級
	char name[30];						//姓名
	char  id[20];						//學號
}StudentInformation;

typedef struct StudentNode				//學生節點
{
	StudentInformation studentinfor;   
	struct StudentNode *Next;
}Student;

 extern GradeData *pHeader_g,*pTail_g;  //成績連結串列頭、尾
 extern Student *pHeader_s,*pTail_s;    //學生連結串列頭、尾         
 extern char textGradeDataFile[20];		//成績資料檔名稱
 extern char textStudentDataFile[20];   //學生資料檔名稱
 extern int isModified;                 //記錄修改是否成功

#endif

StudentInfor.h

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#ifndef ___STUDENT_INFOR_H
#define ___STUDENT_INFOR_H


#include "DataType.h"

//對成績資料及成績節點的基本操作函式(共10個)
void inputGradeData(Grade *pGrade);                 // 輸入成績
void inputGradeDataNode(GradeData *pGradeNode);     // 輸入成績節點
void printGradeData(Grade *pGrade);                 // 輸出成績
void printGradeDataNode(GradeData *pGradeNode);     // 輸出成績節點
void printGradeDataAll();                           // 輸出所有成績節點
void addAtGradeTail(GradeData *pNewNode_g);         // 在成績尾部新增節點
void deleteGradeNode(GradeData *pDeleted);          // 刪除成績節點
void deleteGradeAll();                              // 刪除所有成績節點
void editGradeNode(GradeData *pEdited);             // 編輯成績節點
GradeData *findAGradeData();                        // 通過學號和科目 查詢到準確的成績節點


//對學生資料及學生節點的基本操作函式(共10個)
void inputStudentInformation(StudentInformation *pStudentInfor);                   // 輸入學生資訊
void inputStudentNode(Student *pStudentNode);                                      // 輸入學生節點
void printStudentInformation(StudentInformation *pStuInfor);					   // 輸出學生資訊
void printStudentNode(Student *pStudentNode);						               // 輸出學生節點
void printStudentNodeAll();                                                        // 輸出所有學生節點
void addAtStudentTail(Student *pNewNoStudentNode);						           // 在學生尾部新增節點
void deleteStudentNode(Student *pDeleate);					                       // 刪除學生節點
void deleteStudentAll();														   // 刪除所有學生節點
void editStudentNode(Student *pEdite);						                       // 編輯學生節點
Student *findByStudentId();							                               // 通過學生ID查詢學生節點

#endif

Menu.h

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#ifndef ___MENU_H_
#define ___MENU_H_


#include <stdio.h>
#include <stdlib.h>                                  //提供 malloc() 和 free() 原型和定義

#include "DataType.h"
#include "StudentInfor.h"

//對介面的基本操作及響應函式(共6組,36個)

// 主選單
void drawMainMenu();                                 //繪製主選單
void doMainMenu();                                   //主選單響應
void onMenuitemExit();                               //在選單退出


// 檔案管理 
void drawFileManagementMenu();                       //繪製 檔案管理 子選單
void doFileManagementMenu();                         //檔案管理 子選單 響應

void openGradeDataFromTextFile();                    //從文字讀入 成績資料
void saveGradeDataInTextFile();                      //儲存成績資料到文字
void saveStudentDataInTextFile();					 //儲存學生資料到文字
void openStudentDataFromTextFile();					 //從文字讀入 學生資料


// 資料維護
void drawDataMaintenanceMenu();                      //繪製 資料維護 子選單
void doDataMaintenanceMenu();                        //資料維護 子選單 響應
                   
void drawDataMaintenanceMenu_s();                    //繪製 資料維護 二級子選單(成績)
void doDataMaintenanceMenu_s();                      //資料維護 二級子選單(成績)響應
void onMenueitemAddGrade();							 //在選單新增成績記錄
void onMenuitemEditeGrade();					 	 //在選單編輯成績
void onMenuitemDeleteGrade();						 //在選單刪除成績節點

void drawDataMaintenanceMenu_g();                    //繪製 資料維護 二級子選單(學生)
void doDataMaintenanceMenu_g();                      //資料維護 二級子選單(學生)響應
void onMenueitemAddStudent();						 //在選單新增學生記錄
void onMenuitemEditeStudent();						 //在選單編輯學生
void onMenuitemDeleteStudent();						 //在選單刪除學生節點


// 資料查詢
void drawDataQueryMenu();                            //繪製 資料查詢 子選單
void doDataQueryMenu();                              //資料查詢 子選單 響應

                     
void drawStudentDataQueryMenu();					//繪製 資料查詢 二級子選單(學生)    
void doStudentDataQueryMenu();						//資料查詢 二級子選單(學生) 響應
void onMenueitemBrowseStudent();					//在選單瀏覽學生資料
void onMenueitemSearchStudent();					//在選單查詢學生資料


void drawGradeDataQueryMenu();						//繪製 資料查詢 二級子選單(成績)    
void doGradeDataQueryMenu();						//資料查詢 二級子選單(成績) 響應
void onMenueitemBrowseGradeData();					//在選單瀏覽成績資料
void onMenueitemSearchGradeData();					//在選單查詢成績資料

// 資料統計
void doDataCensuMenu();								//資料統計 子選單 響應
void drawDataCensuMenu();							//繪製 資料統計 子選單 
void onMenueitemStatisticsStudent();				//在選單統計學生成績資訊

//幫助文件
void drawHelpDocumentMenu();                        //繪製 幫助文件 子選單
void doHelpDocumentMenu();                          //幫助文件 子選單 響應

#endif

StudentInfor.c

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "DataType.h"
#include "StudentInfor.h"

 //輸入成績
void inputGradeData(Grade *pGrade)   
{
	printf("學號:");
	scanf("%s",&(pGrade->id));
	printf("學科:");
	scanf("%s",&(pGrade->subject));
	printf("成績:");
	scanf("%f",&(pGrade->grade));
} 
 //輸入成績節點
void inputGradeDataNode(GradeData *pGradeNode)   
{
	inputGradeData(&(pGradeNode->grades));			//輸入成績節點的成績
}  
 //輸出成績
void printGradeData(Grade *pGrade)              
{
	printf("\t%s\t%s\t%f\n",pGrade->id, pGrade->subject, pGrade->grade);
} 
 //輸出成績節點
void printGradeDataNode(GradeData *pGradeNode)  
{
	printGradeData(&(pGradeNode->grades));			//列印成績節點的成績
}

 //輸出所有成績節點
void printGradeDataAll()       
{
	GradeData *p = pHeader_g;						//指標指向成績節的頭
	if(p == NULL)
	{
		puts("沒有成績記錄");
	}
	else
	{
		printf("\t%s\t%s\t%s\n","學號","科目", "成績" );
		while(p!=NULL)
		{
			printGradeDataNode(p);
			p=p->Pnext;
		}
	}
} 

 //在成績尾部新增
void addAtGradeTail(GradeData *pNewNode_g)  
{
	if(pHeader_g == NULL)							//無頭時
	{
		pHeader_g = pTail_g = pNewNode_g;
	}
	else
	{
		pTail_g->Pnext = pNewNode_g;
		pTail_g = pNewNode_g; 
	}
}

 //刪除成績節點
void deleteGradeNode(GradeData *pDeleted)   
{
	GradeData *p,*q;								//成績節點型指標 p, q
	p= q= pHeader_g;								//p,q 賦值為成績頭指標
	while(p!= pDeleted)								//當要刪除的節點不是頭節點時  ,迴圈判斷直到p為要刪除的節點
	{
		q= p;										//q 儲存 P
		p= p->Pnext;								//p 指向該節點的 Pnext 
	}
	if(p== pHeader_g)								//如果p為頭節點 ,此時頭為p的後一個節點,即頭部後移
	{
		pHeader_g= p->Pnext;						//頭指標指向該節點的Pnext
	}
	else if(p== pTail_g)							//如果 p為 尾節點
	{
		q->Pnext= NULL;								//q 的Pnext置空 
		pTail_g= q;									//尾節點改為q ,此時尾為p的前一個節點,即尾部前移
	}
	else											//普通節點時
	{
		q->Pnext= p->Pnext;							//將該節點的前一個節點的Pnext設定為該節點的Pnext
	}
	free(p);										//釋放p

	if(pHeader_g == NULL)							//如果頭部為空則尾部也置空
	{
		pTail_g= NULL;
	}
}
  //刪除所有成績
void deleteGradeAll()       
{
	GradeData *p;
	p= pHeader_g;
	while(pHeader_g != NULL)						//當頭部不為空時
	{
		pHeader_g=p->Pnext;							//頭部後移
		free(p);									//釋放頭部
		p=pHeader_g;								//p 指向新頭部
	}
		pHeader_g = pTail_g = NULL;					//頭、尾置空
} 
  //編輯成績節點
void editGradeNode(GradeData *pEdited)    
{
	printf("輸入成績資訊:");
	inputGradeDataNode(pEdited);					//呼叫函式 輸入成績節點
}
  //通過學號和科目 查詢到準確的成績節點
GradeData *findAGradeData()                       
{	
	GradeData *p;
	int result = 0;
	int result1,result2;
	char buffer[30];  
	char buffer1[30]; 
	char buffer2[30]; 
	gets(buffer);                                  //清除緩衝區殘留
	printf("輸入查詢學號:");
	scanf("%s",&buffer1);
	gets(buffer);                                  //清除緩衝區殘留
	printf("輸入查詢科目:");
	scanf("%s",&buffer2);
	p= pHeader_g;
	while(p!= NULL && !result)							  //迴圈判斷,直至p 指向連結串列尾部
	{
		result1= strcmp(buffer1,(p->grades.id));          //對輸入的學號和 成績節點中的 學號進行 基於字串的比較
		result2= strcmp(buffer2,(p->grades.subject));     //對輸入的科目和 成績節點中的 科目進行 基於字串的比較
		if(result1 == 0 && result2 == 0)				  //如果學號和科目相同 
		{
			return p;
		}
		else										      //不同時,指標p後移動
		{
			p = p->Pnext;
		}
	}
	return NULL;
}                         
  //輸入學生資訊
void inputStudentInformation(StudentInformation *pStudentInfor)	    
{
	char buffer[50];	                                 //用於消除Scanf() 快取區殘留
	printf("任意鍵繼續。。。。\n");
	gets(buffer);
	printf("班級:");
	scanf("%s",pStudentInfor->Class);

	gets(buffer);
	printf("姓名:");
	scanf("%s",pStudentInfor->name);

	gets(buffer);
	printf("學號:");
	scanf("%s",pStudentInfor->id);
}  
  //輸入學生節點
void inputStudentNode(Student*pStudentNode)                                          
{
	inputStudentInformation(&(pStudentNode->studentinfor));
} 
  //輸出學生資訊
void printStudentInformation(StudentInformation *pStuInfor)
{
	printf("\n");
	printf("\t%s",pStuInfor->Class);
	printf("\t%s",pStuInfor->name);
	printf("\t%s",pStuInfor->id);
	printf("\n");
}					  
  //輸出學生節點
void printStudentNode(Student *pStudentNode)
{
	printStudentInformation(&(pStudentNode->studentinfor));
}
  //輸出所有學生節點	
void printStudentNodeAll()
{
	Student *p= pHeader_s;
	if(p == NULL)
	{
		puts("沒有記錄\n");
		exit(-1);
	}
	else
	{
		printf("\t%s\t%s\t%s","班級","姓名","學號");
		while(p!= NULL)
		{
			printStudentNode(p);
			p= p->Next;
		}
	}
}
  //在學生尾部新增節點                                                       					                                   
void addAtStudentTail(Student *pNewNoStudentNode)
{
	if(pHeader_s==NULL)                               //無頭時
	{
		pHeader_s= pTail_s= pNewNoStudentNode;
	}
	else
	{
		pTail_s->Next= pNewNoStudentNode;
		pTail_s= pNewNoStudentNode;
	}
}		
  //刪除學生節點
void deleteStudentNode(Student *pDeleate)
{
	Student *p,*q;                                    //學生節點型指標 p, q
	p= q= pHeader_s;								  //p,q 賦值為成績頭指標
	while(p!= pDeleate)                               //找到要刪除的學生節點 記為 p
	{
		q= p;                                         //q 儲存 P
		p= p->Next;                                   //p 賦值為 p->Next
	}
	if(p == pHeader_s)                                //如果是頭
	{
		pHeader_s= p->Next;
	}
	else if(p == pTail_s)                             //如果是尾
	{
		q->Next= NULL;
		pTail_s= q;
	}
	else
	{
		q->Next= p->Next;
	}
	free(p);
	if(pHeader_s== NULL)
	{
		pTail_s= NULL;
	}
}	
  //刪除所有學生節點
void deleteStudentAll()
{	
	Student *p;
	p= pHeader_s;
	while(pHeader_s != NULL)						     //當頭部不為空時
	{
		pHeader_s=p->Next;							     //頭部後移
		free(p);									     //釋放頭部
		p=pHeader_s;							         //p 指向新頭部
	}
		pHeader_s = pTail_s = NULL;					     //頭、尾置空
}				
  //編輯學生節點	
void editStudentNode(Student *pEdite)
{
	printf("請輸入學生資訊:\n");
	inputStudentNode(pEdite);
}
  //通過學生ID查詢	
Student *findByStudentId()
{
	Student *p;                                             //學生節點型指標 *p
	int result;
	char buffer[30];  
	gets(buffer);                                          //清除緩衝區殘留
	printf("輸入查詢學號:");
	scanf("%s",&buffer);
	p= pHeader_s;
	while(p!= NULL)							               //迴圈判斷,直至p 指向連結串列尾部
	{
		result= strcmp(buffer,(p->studentinfor.id));       //對輸入的學號和 學生節點中的 學號進行 基於字串的比較
		if(result == 0 )				                   //如果學號相同 
		{
			return p;
		}
		else										       //不同時,指標p後移動
		{
			p = p->Next;
		}
	}
	return NULL;
}							                               				                                       			  				                                      			           

Menu.c

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#include "Menu.h"
#include "StudentInfor.h"

//繪製主選單
void drawMainMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t學生成績管理系統              ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t   系統主介面                 ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、檔案管理   ==========  請按F(f)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、資料維護   ==========  請按M(m)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、資料查詢   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t4、資料統計   ==========  請按C(c)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t6、退出系統   ==========  請按Q(q)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");

} 
//主選單響應 
void doMainMenu()
{
	int done = 0;
	char cmd[2];

	openGradeDataFromTextFile();									//從文字讀入成績資料
	openStudentDataFromTextFile();									//從文字讀入學生資料
	system("pause");

	while(!done)
	{
		char buffer[1000];
		drawMainMenu();                                              //繪製主選單
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'F':
		case 'f':
			doFileManagementMenu();									//檔案管理 子選單 響應
			break;
		case 'M':
		case 'm':
			doDataMaintenanceMenu();								//資料維護 子選單 響應
			break;
		case 'S':
		case 's':
			doDataQueryMenu();										//資料查詢 子選單 響應
			break;
		case 'C':
		case 'c':
			doDataCensuMenu();										//資料統計 子選單 響應
			break;
		case 'H':
		case 'h':
			doHelpDocumentMenu(); 									//幫助文件 子選單 響應
			break;
		case 'Q':
		case 'q':
			onMenuitemExit();                                       //在選單退出
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
	saveGradeDataInTextFile();										//退出系統預設儲存成績資料
	saveStudentDataInTextFile();									//退出系統預設儲存學生資料
	system("pause");
}  
//在選單退出
void onMenuitemExit()
{
	char cmd[2];
	if(isModified);
	{
		puts("資料已修改,是否存檔?");
		scanf("%s",cmd);
		if(cmd[0]== 'Y' || cmd[0]=='y')                              //存檔,退出成績
		{
			//onMenuitemSave();
			saveGradeDataInTextFile();								 //儲存成績資料
			saveStudentDataInTextFile();							 //儲存學生資料
			system("pause");
			exit(0);
		}
	}
	//deleteAll();
	deleteStudentAll();                                              // 刪除所有學生節點
	deleteGradeAll();                                                // 刪除所有成績節點
}                                                               
//繪製 檔案管理 子選單
void drawFileManagementMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    檔案管理                  ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、匯入檔案   ==========  請按O(o)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、儲存檔案   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t4、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
} 
//檔案管理子選單響應
void doFileManagementMenu()
{	
	int done = 0;
	char cmd[2];

	while(!done)
	{	char buffer[1000];
		drawFileManagementMenu();                                       //繪製 檔案管理 子選單
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'O':
		case 'o':
			openGradeDataFromTextFile();								//從文字讀入 成績 資料
			openStudentDataFromTextFile();								//從文字讀入 學生 資料
			break;
		case 'S':
		case 's':
			saveGradeDataInTextFile();									//儲存 成績 資料 到文字
			saveStudentDataInTextFile();								//儲存 學生 資料 到文字
			system("pause");
			break;
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}	
}    
// 從文字讀入成績資料 
void openGradeDataFromTextFile()
{
	/*
	//隨機讀寫版本

	long int q,len, nowfp,diff;                                         //q儲存偏移差值,len檔案尾偏移量,nowfp當前偏移量, diff偏移差值
	long int d=0;
	GradeData *newGradeDataNode= NULL;
	FILE *inFile= NULL;

	deleteGradeAll();													//在讀取文字前 清空所有連結串列節點
	inFile= fopen(textGradeDataFile,"rt");							//用fopen()只讀開啟一個文字檔案,只允許讀資料
	if(inFile==NULL)
	{
		printf("無法開啟文字 %s.txt",textGradeDataFile);
		exit(-1);
	}

	nowfp =ftell(inFile);	
	fseek(inFile, 0,SEEK_END);											//移動檔案指標到檔案尾部
	len =ftell(inFile);													//獲取當前檔案針相對檔案首部的偏移量
	fseek(inFile, 0,SEEK_SET);											//移動檔案指標到檔案頭部
	q= nowfp =ftell(inFile);											//獲取並儲存當前偏移量
	newGradeDataNode= (GradeData*)malloc(sizeof(GradeData));			//在堆中開闢空間
	newGradeDataNode->Pnext= NULL; 
  
	fscanf(inFile,"%s%s%f",&(newGradeDataNode->grades).id,&(newGradeDataNode->grades).subject,&(newGradeDataNode->grades).grade);
	free(newGradeDataNode);												//釋放臨時儲存區
	nowfp =ftell(inFile);												//獲取當前偏移量

	diff= nowfp - q + 1;												//得到一次讀取偏移差值
	fseek(inFile, 0,SEEK_SET);											//移動檔案指標到檔案頭部
	nowfp =ftell(inFile);												//獲取當前偏移量
	//while(!feof(inFile));
	if(nowfp== len)
	{
	  printf("\n從檔案讀入資料\n");
	}
	  while(nowfp <= (len-diff))
	{
		newGradeDataNode= (GradeData*)malloc(sizeof(GradeData));       //在堆中開闢空間
		if(newGradeDataNode ==NULL)
		{
			puts("記憶體不足,無法讀取資料");
		}
		else
		{
			newGradeDataNode->Pnext= NULL;
			fscanf(inFile,"%s%s%f",&(newGradeDataNode->grades).id,&(newGradeDataNode->grades).subject,&(newGradeDataNode->grades).grade);
			nowfp=ftell(inFile);                                        //更新當前偏移量
			addAtGradeTail(newGradeDataNode);							//在成績尾部新增節點
		}
		d++;
	}
	fclose(inFile);
	printf("\n已讀入%d條成績資訊\n",d);
	*/

	GradeData *newGradeDataNode= NULL;
	FILE *inFile= NULL;
	int d=0;
	deleteGradeAll();	//在讀取文字前 清空所有連結串列節點

	inFile= fopen(textGradeDataFile,"rt");							//用fopen()只讀開啟一個文字檔案,只允許讀資料
	if(inFile==NULL)
	{
		printf("無法開啟文字 %s.txt",textGradeDataFile);
		exit(-1);
	}

	newGradeDataNode= (GradeData*)malloc(sizeof(GradeData));       //在堆中開闢空間
	newGradeDataNode->Pnext= NULL; 
	fscanf(inFile,"%s%s%f",&(newGradeDataNode->grades).id,&(newGradeDataNode->grades).subject,&(newGradeDataNode->grades).grade);
	while(!feof(inFile))
	{
			addAtGradeTail(newGradeDataNode);							//在成績尾部新增節點
			newGradeDataNode= (GradeData*)malloc(sizeof(GradeData));       //在堆中開闢空間
			newGradeDataNode->Pnext= NULL; 
			fscanf(inFile,"%s%s%f",&(newGradeDataNode->grades).id,&(newGradeDataNode->grades).subject,&(newGradeDataNode->grades).grade);
			d++;
	}
	free(newGradeDataNode);
	fclose(inFile);
	printf("已經讀入: %d",d);
}          
// 儲存成績資料到文字
void saveGradeDataInTextFile()
{
	GradeData *p= pHeader_g;
	FILE *outFile= NULL;
	int d=0;
	outFile= fopen(textGradeDataFile,"wt");    //用fopen()只寫開啟或建立一個文字檔案,只允許寫資料
	if(outFile == NULL)
	{
		printf("無法開啟文字 %s.txt",textGradeDataFile);
	}

	if(p== NULL)
	{
		puts("沒有記錄!");
	}
	else
	{
		while(p!= NULL)
		{
			fprintf(outFile,"%15s%15s%15f\n",p->grades.id,p->grades.subject,p->grades.grade);
			p= p->Pnext;
			d++;
		}
	}
	fclose(outFile);
	printf("成績資料已儲存%d\n",d);
}
//從文字讀入 學生資料 
void openStudentDataFromTextFile()
{
	long int q,len, nowfp,diff;                                         //q儲存偏移差值,len檔案尾偏移量,nowfp當前偏移量, diff偏移差值
	long int d=0;
	Student *newStudentDataNode= NULL;
	FILE *inFile= NULL;
	deleteStudentAll();													//在讀取文字前 清空所有連結串列節點
	inFile= fopen(textStudentDataFile,"rt");							//用fopen()只讀開啟一個文字檔案,只允許讀資料
	if(inFile==NULL)
	{
		printf("無法開啟文字 %d.txt",textStudentDataFile);
		exit(-1);
	}

	nowfp =ftell(inFile);	
	fseek(inFile, 0,SEEK_END);											//移動檔案指標到檔案尾部
	len =ftell(inFile);													//獲取當前檔案針相對檔案首部的偏移量
	fseek(inFile, 0,SEEK_SET);											//移動檔案指標到檔案頭部
	q= nowfp =ftell(inFile);											//獲取並儲存當前偏移量
	newStudentDataNode= (Student*)malloc(sizeof(Student));				//在堆中開闢空間
	newStudentDataNode->Next= NULL; 
  
	fscanf(inFile,"%s%s%s",&(newStudentDataNode->studentinfor).Class,&(newStudentDataNode->studentinfor).name,&(newStudentDataNode->studentinfor).id);
	free(newStudentDataNode);											//釋放臨時儲存區
	nowfp =ftell(inFile);												//獲取當前偏移量

	diff= nowfp - q + 1;												//得到一次讀取偏移差值
	fseek(inFile, 0,SEEK_SET);											//移動檔案指標到檔案頭部
	nowfp =ftell(inFile);												//獲取當前偏移量
	//while(!feof(inFile));
	while(nowfp <= (len-diff))
	{
		newStudentDataNode= (Student*)malloc(sizeof(Student));			//在堆中開闢空間
		if(newStudentDataNode ==NULL)
		{
			puts("記憶體不足,無法讀取資料");
		}
		else
		{
			newStudentDataNode->Next= NULL;
			fscanf(inFile,"%s%s%s",&(newStudentDataNode->studentinfor).Class,&(newStudentDataNode->studentinfor).name,&(newStudentDataNode->studentinfor).id);
			nowfp=ftell(inFile);                                        //更新當前偏移量
			addAtStudentTail(newStudentDataNode);						//在學生尾部新增節點
		}
		d++;

	}
	fclose(inFile);
	printf("已讀入%d條學生資訊\n",d);

}					 
//儲存學生資料到文字
void saveStudentDataInTextFile()
{
	Student *p= pHeader_s;
	FILE *outFile= NULL;
	int d=0;
	outFile= fopen(textStudentDataFile,"wt");    //用fopen()只寫開啟或建立一個文字檔案,只允許寫資料
	if(outFile == NULL)
	{
		printf("無法開啟文字 %s.txt",textStudentDataFile);
	}

	if(p== NULL)
	{
		puts("沒有記錄!");
	}
	else
	{
		while(p!= NULL)
		{
			fprintf(outFile,"%15s%15s%15s\n",p->studentinfor.Class,p->studentinfor.name,p->studentinfor.id);
			p= p->Next;
			d++;
		}
	}
	fclose(outFile);
	printf("\n學生資料已儲存%d條\n",d);
}					                     
//繪製 資料維護 子選單                      
void drawDataMaintenanceMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    資料維護                  ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、學生資料維護 ========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、成績資料維護 ========  請按G(g)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t4、使用幫助     ========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回         ========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
}
//資料維護 子選單 響應
void doDataMaintenanceMenu()
{
	
	int done = 0;
	char cmd[2];
	while(!done)
	{
		char buffer[1000];
		drawDataMaintenanceMenu();                                   //資料維護 子選單
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'S':
		case 's':
			doDataMaintenanceMenu_s();                               // 資料維護 二級子選單(學生)響應
			break;
		case 'G':
		case 'g':
			doDataMaintenanceMenu_g();                               // 資料維護 二級子選單(成績)響應		
			break;
		case 'H':
		case 'h':
			doHelpDocumentMenu();                                    //幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}

	}

}
// 繪製 資料維護 二級子選單(學生)
void drawDataMaintenanceMenu_s()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    學生資料維護              ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、新增記錄   ==========  請按A(a)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、修改記錄   ==========  請按E(e)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、刪除記錄   ==========  請按D(d)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t4、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");

}
// 資料維護 二級子選單(學生)響應                   
void doDataMaintenanceMenu_s()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawDataMaintenanceMenu_s();                                         // 繪製 資料維護 二級子選單(學生)
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'A':
		case 'a':
			onMenueitemAddStudent();										//在選單新增學生記錄
			break;
		case 'E':
		case 'e':
			onMenuitemEditeStudent();										//在選單編輯學生		
			break;
		case 'D':
		case 'd':
			onMenuitemDeleteStudent();									    //在選單刪除學生節點
			break;
		case 'H':
		case 'h':
			doHelpDocumentMenu();											//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}

} 
// 在選單新增學生記錄
void onMenueitemAddStudent()						 
{
	Student *newNode;                                                //建立新學生節點記錄
	newNode= (Student*) malloc(sizeof(Student));                     //依據學生結構體的資料大小在堆中分配記憶體

	if(newNode == NULL)                                              //當記憶體分配失敗時
	{
		puts("記憶體不足,無法建立");
		exit(-1);
	}
	system ("cls");
	inputStudentNode(newNode);                                      // 輸入學生節點
	newNode->Next= NULL;	
	addAtStudentTail(newNode);										// 在學生尾部新增節點
	puts("記錄新增成功! ");
	printStudentNode(pTail_s);										// 輸出學生節點
	system ("pause");
	isModified= 1;
}
//在選單編輯學生
void onMenuitemEditeStudent()
{
	Student *pFound;
	printf("請輸入要編輯的學生的相關資訊:\n");
	pFound= findByStudentId();              //pFound 為通過學生ID查詢到的學生節點
	if(pFound != NULL)
	{
		system("cls");
		editStudentNode(pFound);			         //通過pFound 編輯學生節點
		printf("記錄已修改 。\n");
		printStudentNode(pFound);                    //列印修改後的學生節點
		isModified= 1;                               //標識修改成功
	}
	else
	{
		puts("沒有要修改的記錄!");
	}
	system("pause");	
}
//在選單刪除學生節點
void onMenuitemDeleteStudent()
{
	Student *pFound;
	printf("請輸入要刪除學生的相關資訊:\n");
	pFound= findByStudentId();							//pFound 為通過學號查詢到的結果
	if(pFound != NULL)
	{
		system("cls");
		deleteStudentNode(pFound);                      //通過pFound 刪除成績節點
		printf("記錄已刪除 。\n");
		printStudentNodeAll();                          //輸出所有學生節點

		isModified= 1;                                  //標識修改成功
	}
	else
	{
		puts("沒有要刪除的記錄!");
	}
	system("pause");

}						 						 								 




//繪製 資料維護 二級子選單(成績)                    
void drawDataMaintenanceMenu_g()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    成績資料維護              ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、新增記錄   ==========  請按A(a)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、修改記錄   ==========  請按E(e)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、刪除記錄   ==========  請按D(d)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t4、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
}
//資料維護 二級子選單(成績)響應                   
void doDataMaintenanceMenu_g()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawDataMaintenanceMenu_g();										//繪製 資料維護 二級子選單(成績)
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'A':
		case 'a':
			onMenueitemAddGrade();										//在選單新增成績記錄
			break;
		case 'E':
		case 'e':
			onMenuitemEditeGrade();										//在選單編輯成績		
			break;
		case 'D':
		case 'd':
			onMenuitemDeleteGrade();									//在選單刪除成績節點
			break;
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
}                      
 //在選單新增成績記錄
void onMenueitemAddGrade() 
{
	GradeData *newNode;                               //建立新成績節點記錄
	newNode= (GradeData*) malloc(sizeof(GradeData));  //依據成績結構體的資料大小在堆中分配記憶體

	if(newNode == NULL)                               //當記憶體分配失敗時
	{
		puts("記憶體不足,無法建立");
		exit(-1);
	}

	system ("cls");
	inputGradeDataNode(newNode);                      //輸入成績節點資訊
	newNode->Pnext= NULL;
	
	addAtGradeTail(newNode);						  //在成績連結串列尾部新增
	puts("記錄新增成功! ");
	printGradeDataNode(pTail_g);					  //輸出已新增的成績節點
	system ("pause");
	isModified= 1;

}
  //在選單編輯成績
void onMenuitemEditeGrade()  
{
	GradeData *pFound= findAGradeData();               //pFound 為通過學號和科目查詢到的結果
	if(pFound != NULL)
	{
		system("cls");
		editGradeNode(pFound);                         //通過pFound 編輯成績節點
		printf("記錄已修改 。\n");
		printGradeDataNode(pFound);                    //列印修改後的節點
		isModified= 1;                                 //標識修改成功
	}
	else
	{
		puts("沒有要修改的記錄!");
	}
	system("pause");
}
 //在選單刪除成績節點
void onMenuitemDeleteGrade()   
{
	GradeData *pFound= findAGradeData();                 //pFound 為通過學號和科目查詢到的結果
	if(pFound != NULL)
	{
		system("cls");
		deleteGradeNode(pFound);                        //通過pFound 刪除成績節點
		printf("記錄已刪除 。\n");
		printGradeDataAll();                            //輸出所有成績節點

		isModified= 1;                                  //標識修改成功
	}
	else
	{
		puts("沒有要刪除的記錄!");
	}
	system("pause");
}
//繪製 資料查詢 子選單                      
void drawDataQueryMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    資料查詢                  ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、學生資料   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、成績資料   ==========  請按G(g)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
}
// 資料查詢 子選單 響應
void doDataQueryMenu()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawDataQueryMenu();											//繪製 資料查詢 子選單
		printf("任意鍵繼續。\n");
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'S':
		case 's':  
			doStudentDataQueryMenu();									//資料查詢 二級子選單(學生) 響應 
			break;
		case 'G':
		case 'g':						    
			doGradeDataQueryMenu();										//資料查詢 二級子選單(成績) 響應
			break;				
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
}   
//繪製 資料查詢 二級子選單(學生)                      
void drawStudentDataQueryMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    學生資料查詢              ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、瀏覽資料   ==========  請按B(B)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、查詢資料   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
}
//資料查詢 二級子選單(學生) 響應   
void doStudentDataQueryMenu()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawStudentDataQueryMenu();										//繪製 資料查詢 二級子選單(學生)  
		printf("任意鍵繼續。\n");
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'B':
		case 'b':  
			onMenueitemBrowseStudent();									//在選單瀏覽學生資料
			break;
		case 'S':
		case 's':						    					
			onMenueitemSearchStudent();									//在選單查詢學生資料
			break;				
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
}
//在選單瀏覽學生資料
void onMenueitemBrowseStudent()
{
	printStudentNodeAll();                                              // 輸出所有學生節點
	system("pause");
}
//在選單查詢學生資料					
void onMenueitemSearchStudent()
{
	Student *pFound;

	pFound= findByStudentId();							                // pFound為通過學生ID查詢到的學生節點
	if(pFound != NULL)
	{
		printStudentNode(pFound);										// 輸出查詢到的學生節點
	}
	else
	{
		puts("未查詢到相關資訊!");
	}
	system("pause");
}					
//繪製 資料查詢 二級子選單(成績)
void drawGradeDataQueryMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    成績資料查詢              ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、瀏覽資料   ==========  請按B(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、查詢資料   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t5、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");

}
//資料查詢 二級子選單(成績) 響應						    
void doGradeDataQueryMenu()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawGradeDataQueryMenu();										   //繪製 資料查詢 二級子選單(成績) 
		printf("任意鍵繼續。\n");
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'B':
		case 'b':  
			onMenueitemBrowseGradeData();								//在選單瀏覽成績資料
			break;
		case 'S':
		case 's':					
			onMenueitemSearchGradeData();								//在選單查詢成績資料
			break;				
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
}
//在選單瀏覽成績資料
void onMenueitemBrowseGradeData()
{
	printGradeDataAll();												// 輸出所有成績節點
	system("pause");
}
//在選單查詢成績資料					
void onMenueitemSearchGradeData()
{
	GradeData *pFound;

	pFound= findAGradeData(); 							                // pFound為通過學生ID和科目查詢到的成績節點
	if(pFound != NULL)
	{
		printGradeDataNode(pFound);										// 輸出查詢到的成績節點
	}
	else
	{
		puts("未查詢到相關資訊!");
	}
	system("pause");
}	

// 繪製 資料統計 子選單 
void drawDataCensuMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    資料統計                  ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、學生統計   ==========  請按S(s)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t2、使用幫助   ==========  請按H(h)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t3、返回       ==========  請按R(r)    ##\n");
	printf("\t##                                            ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");

}								
//資料統計 子選單 響應										
void doDataCensuMenu()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawDataCensuMenu();											// 繪製 資料統計 子選單
		printf("任意鍵繼續。\n");
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'S':
		case 's':
			onMenueitemStatisticsStudent();								//在選單統計學生成績資訊
			break;	
		case 'H':
		case 'h':
			doHelpDocumentMenu();										//幫助文件 子選單 響應
			break;
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}
}
//在選單統計學生成績資訊
void onMenueitemStatisticsStudent()
{
	Student *pFound;
	GradeData *p= pHeader_g;							//指標指向成績節的頭
	char buffer[30];  
	char buffer1[30];
	int result = 0;
	float Sumgrade=0.0;									//總成績
	float num=0.0;										//科目數
	gets(buffer);										//清除緩衝區殘留
	printf("輸入查詢學號:");
	scanf("%s",&buffer1);
	pFound= findByStudentId();							// pFound為通過學生ID查詢到的學生節點
	if(pFound != NULL)
	{
		printStudentNode(pFound);						// 輸出查詢到的學生節點
	}
	else
	{
		puts("未查詢到相關學生資訊!");
	}	
	if(p == NULL)
	{
		puts("沒有成績記錄");
	}
	while(p!= NULL)							              //迴圈判斷,直至p 指向連結串列尾部 
	{
		result= strcmp(buffer1,(p->grades.id));           //對輸入的學號和 成績節點中的 學號進行 基於字串的比較
		if(result == 0 )								  //如果學號相同 
		{
			printGradeDataNode(p);						  // 輸出成績節點
			Sumgrade+=p->grades.grade;                    //成績增加
			num++;                                        //科目數增加
		}									      
		p = p->Pnext;									  //不同時,指標p後移動
	}
	if(num== 0.0)
		num=1.0;
	printf("\n\t總成績:%f\t平均成績: %f\n",Sumgrade,Sumgrade/num);
	system("pause");
}  
                        
// 繪製 幫助文件 子選單                          
void drawHelpDocumentMenu()
{
	system("cls");                                                    //清屏
	printf("\n");
	printf("\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\t    使用幫助                  ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t                                      ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t1、請依照介面提示進行相應輸入         ##\n");
	printf("\t##                                            ##\n");
	printf("\t##\t                                      ##\n");
	printf("\t##\t2、返回       ==========  請按R(r)    ##\n");
	printf("\t##\t                                      ##\n");
	printf("\t##                                            ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
	printf("\t##                                            ##\n");
	printf("\t##\t\tMaked By : smallerXuan        ##\n");
	printf("\t##                                            ##\n");
	printf("\t################################################\n");
}                         
//幫助文件 子選單 響應             
void doHelpDocumentMenu()
{
	int done = 0;
	char cmd[2];

	while(!done)
	{	
		char buffer[1000];
		drawHelpDocumentMenu();                                             // 繪製 幫助文件 子選單 
		gets(buffer);                                                
		printf("請輸入選項:");
		scanf("%s",cmd);
		switch(cmd[0])
		{
		case 'R':
		case 'r':
			done = 1;	
			break;
		default:
			printf("輸入有誤,請從新輸入");
		}
	}	
}     
                                


StudentAchievementManagementSystemStart.c

/*
編譯環境:VS2017\Windows10
作者:smallerXuan
指導:
*/

#include <stdio.h>
#include "DataType.h"
#include "StudentInfor.h"
#include "Menu.h"


 GradeData *pHeader_g=NULL,*pTail_g=NULL;									//成績連結串列頭、尾
 Student *pHeader_s=NULL,*pTail_s=NULL;										//學生連結串列頭、尾
 char textGradeDataFile[20]= "textGradeDataFile";							//成績資料檔名稱
 char textStudentDataFile[20]= "textStudentDataFile";					    //學生資料檔名稱
 int isModified=0;															//記錄修改是否成功


int main (void)
{
	doMainMenu();

	return 0;
}