#include<stdio.h>
#include<stdlib.h> //基本庫函數
#include<string.h> //字符串處理函數
#include<conio.h> //包含字符模式的圖形函數,如:清屏、清行、向後刪行、插行等
#define LEN sizeof(struct student) //宏定義
struct student
{
long num; //學號
char name[20]; //姓名
float score[3]; //成績
float ave; //平均成績
struct student *next;
};
int N; /* 全局變量,結點的個數 */
struct student *head; /* 全局變量, 所處理鏈表的頭指針 */
int FLAG; /* 全局變量FLAG,文件是否保存:1表示沒有保存,0表示已經保存 */
char filename[20]; /* 全局變量,存放文件名 */
struct student *input(void); /* 函數聲明 */
void print(void);
void search(void);
void sort(void);
void insert(void);
void save(void);
float average(float s[]);
void load(void);
void sort_ave() /* 定義按平均分排序的函數 */
{
int i,j,k;
struct student *p1,*p2,*p;
if(head==NULL)
printf("錯誤!記錄為空!請輸入記錄.\n");
else /* 用起泡法思想排序 */
{
for(j=0;j<N-1;j++) //外層循環次數:節點個數-1
{
p1=head;
for(i=0;i<N-1-j;i++)
{
p=head;
p2=p1->next;
if(p1->ave<p2->ave)
{
p1->next=p2->next;
p2->next=p1;
if(head==p1) /* 若p1指向頭指針所指,則頭指針指向p2所指 */
head=p2;
else
{
for(k=0;k<i-1;k++) /* 令p指向p1所指結點的前壹個結點 */
p=p->next;
p->next=p2;
}
}
else p1=p1->next;
}
}
FLAG=0; /* 標誌當前數據已改動 */
printf("記錄已經排序!\n");
}
}
void sort_num() /* 定義按學號排序的函數 */
{
int i,j,k;
struct student *p1,*p2,*p;
if(head==NULL)
printf("錯誤!記錄為空!請輸入記錄.\n");
else
{
for(j=0;j<N-1;j++)
{
p1=head;
for(i=0;i<N-1-j;i++)
{
p=head;
p2=p1->next;
if(p1->num>p2->num)
{
p1->next=p2->next;
p2->next=p1;
if(head==p1)
head=p2;
else
{
for(k=0;k<i-1;k++)
p=p->next;
p->next=p2;
}
}
else p1=p1->next;
}
}
FLAG=0;
printf("記錄已經排序!\n");
}
}
void sort()
{
char c0;
c0=getchar(); /* 接收回車符 */
system("cls");
printf("請選擇:\n\n");
printf("1. 按平均分排序\n");
printf("2. 按學號排序\n");
printf("3. 返回\n");
c0=getchar();
while(c0!='3')
{
printf("\n\n");
printf("********************************************************\n");
if(c0=='1') sort_ave();
else if(c0=='2') sort_num();
printf("\n******************************************************\n");
c0=getchar(); /* 接收回車符 */
printf("\nPress any key to continue:");
getch();
system("cls");
printf("請選擇:\n\n");
printf("1. 按平均分排序\n");
printf("2. 按學號排序\n");
printf("3. 返回\n");
c0=getchar();
}
}
struct student *input() //輸入學生成績信息,構造學生鏈表
{
float average(float s[]);
struct student *stu,*p1,*p2;
int i;
N=0;
stu=(struct student *)malloc(LEN);
p1=p2=stu;
printf("輸入學號 :");
scanf("%ld",&stu->num);
printf("\n輸入姓名 :");
scanf("%s",stu->name);
for(i=0;i<3;i++)
{
printf("\n輸入課程%d",i+1);
scanf(" %f",&stu->score[i]);
}
stu->ave=average(stu->score);
//構造鏈表
while(p1->num!=0) //p1->num等於0,表示停止輸入
{ N=N+1;
if(N==1) head=p1;
else {p2->next=p1;p2=p1;}
stu=(struct student *)malloc(LEN);
p1=stu;
printf("\n輸入學號:");
scanf("%ld",&stu->num);
if(p1->num!=0)
{
printf("\n輸入姓名:");
scanf("%s",stu->name);
for(i=0;i<3;i++)
{
printf("\n輸入課程%d:",i+1);
scanf("%f",&stu->score[i]);
}
stu->ave=average(stu->score);
}
}
p2->next=NULL;
FLAG=0;
return(head);
}
float average(float s[]) //計算平均成績
{
float a,sum=0;
int i;
for(i=0;i<3;i++)
sum=sum+s[i];
a=sum/3;
return(a);
}
void insert()
{
int i;
struct student *p0,*p1,*p2,*stu;
sort_ave();
stu=(struct student *)malloc(LEN);
printf("\n輸入學號:");
scanf("%ld",&stu->num);
printf("\n輸入姓名:");
scanf("%s",stu->name);
for(i=0;i<3;i++)
{
printf("\n輸入課程%d:",i+1);
scanf("%f",&stu->score[i]);
}
stu->ave=average(stu->score);
p0=stu;
p1=head;
if(head==NULL) {head=p0;p0->next=NULL;}
else
{
while((p1->ave>p0->ave)&&(p1->next!=NULL))
{p2=p1;p1=p1->next;}
if(p1->ave<=p0->ave)
{
if(p1==head)
{
head=p0;
p0->next=p1;
}
else {p0->next=p1;p2->next=p0;}
}
else
{
p1->next=p0;
p0->next=NULL;
}
}
N=N+1;
FLAG=0;
printf("\n現在的記錄是:\n\n");
print();
}
void load(void)
{
FILE *fp;
struct student *p,*p0;
int i,flag=1;
printf("請輸入文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open infile\n");
return;
}
if(fread(&N,sizeof(int),1,fp)!=1) //
{
if(feof(fp))
{
fclose(fp);
return;
}
printf("file read error\n");
flag=0;
}
fseek(fp,sizeof(int),0);
head=p=(struct student *)malloc(LEN);
for(i=0;i<N;i++)
{
fread(p,sizeof(struct student),1,fp);
p0=(struct student *)malloc(LEN);
p->next=p0;
p0=p;
p=p->next;
}
p0->next=NULL;
if(flag) printf("成功讀取記錄!\n");
fclose(fp);
}
void print() //把鏈表中的學生成績信息輸出到屏幕上
{
struct student *p;
if(head==NULL)
printf("錯誤!記錄為空!請輸入記錄.\n");
else
{
p=head;
printf("\t 學號 姓名 課程1 課程2 課程3 平均成績\n");
while(p!=NULL)
{
printf("\t -----------------------------------------------------------\n"); //-:有-表示左對齊輸出,如省略表示右對齊輸出。
printf("\t %-10ld %-8s| %-10.2f| %-10.2f| %-10.2f| %-10.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2],p->ave);
p=p->next;
}
}
}
void save()
{
FILE *fp;
struct student *p;
int i,flag=1;
printf("輸入文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"wb"))==NULL)
{
printf("\nCan not open file\n");
return;
}
if(fwrite(&N,sizeof(int),1,fp)!=1) //
{
printf("\nfile write error\n");
flag=0;
}
fseek(fp,sizeof(int),0); //
p=head;
while(p!=NULL)
{
if(fwrite(p,LEN,1,fp)!=1)
{
printf("\nfile write error\n");
flag=0;
}
p=p->next;
}
if(flag)
{
FLAG=1;
printf("文件已經保存!\n");
}
fclose(fp);
}
void search_name()
{
struct student *p;
char sear_name[20];
int flag=0;
if(head==NULL)
printf("錯誤!記錄為空!請輸入記錄.\n");
else
{
p=head;
printf("請輸入要查找學生的姓名:\n");
scanf("%s",sear_name);
printf("\n\n");
while(p!=NULL)
{
if(strcmp(sear_name,p->name)==0)
{
if(!flag)
{
printf("該學生的記錄如下:\n\n");
printf("\t 學號 姓名 課程1 課程2 課程3 平均成績\n");
}
printf("\t ----------------------------------------------------------\n");
printf("\t %-8ld%-8s|%-10.2f|%-10.2f|%-10.2f|%-10.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2],p->ave);
flag=1;
}
p=p->next;
}
if(!flag) printf("沒有查找到記錄!\n");
}
}
void search_num()
{
struct student *p;
long number;
int flag=0;
if(head==NULL)
printf("錯誤!記錄為空!請輸入記錄.\n");
else
{
p=head;
printf("請輸入要查找學生的學號:\n");
scanf("%ld",&number);
printf("\n\n");
while(p!=NULL&&!flag)
{
if(number==p->num)
{
printf("該學生的記錄如下:\n\n");
printf("\t 學號 姓名 課程1 課程2 課程3 平均成績\n");
printf("\t ----------------------------------------------------------\n");
printf("\t %-8ld%-8s|%-10.2f|%-10.2f|%-10.2f|%-10.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2],p->ave);
flag=1;
}
p=p->next;
}
if(!flag) printf("沒有查找到記錄!\n");
}
}
void search()
{
char c0;
c0=getchar();
system("cls");
printf("請選擇:\n\n");
printf("1. 姓名查找\n");
printf("2. 學號查找\n");
printf("3. 返回\n");
c0=getchar();
while(c0!='3')
{
printf("\n\n");
printf("********************************************************************************\n");
if(c0=='1') search_name();
else if(c0=='2') search_num();
printf("\n********************************************************************************\n");
c0=getchar();
printf("\nPress any key to continue:");
getch();
system("cls");
printf("請選擇:\n\n");
printf("1. 姓名查找\n");
printf("2. 學號查找\n");
printf("3. 返回\n");
c0=getchar();
}
}
int main(int argc, char *argv[])
{
char c,c0;
head=NULL;
FLAG=1; //初始時信息未保存
system("cls"); //清屏
//printf("\001"); 打印出壹個特殊字符
printf("\001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001\n");
printf("\n\t\t\t 歡迎使用學生成績管理系統!\n\n");
printf("\001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001 \001\n");
printf("1. 輸入記錄\n");
printf("2. 輸出記錄\n");
printf("3. 查找記錄\n");
printf("4. 排序\n");
printf("5. 插入記錄\n");
printf("6. 保存記錄到文件\n");
printf("7. 從文件讀取記錄\n");
printf("0. 退出\n");
printf("\n\n請選擇:\n\n");
c=getchar();
while(c!='0')
{
if(c!='3'&&c!='4')
{
printf("\n\n");
printf("********************************************************************************\n");
}
if(c=='1') head=input();
else if(c=='2') print();
else if(c=='3') search();
else if(c=='4') sort();
else if(c=='5') insert();
else if(c=='6') save();
else if(c=='7') load();
if(c!='3'&&c!='4')
{
printf("\n********************************************************************************\n");
printf("按任意鍵繼續:");
c=getchar(); //
getch(); //等待妳按下任意鍵,再繼續執行下面的語句
}
else c=getchar();
system("cls"); //清屏
printf("1. 輸入記錄\n");
printf("2. 輸出記錄\n");
printf("3. 查找記錄\n");
printf("4. 排序\n");
printf("5. 插入記錄\n");
printf("6. 保存記錄到文件\n");
printf("7. 從文件讀取記錄\n");
printf("0. 退出\n");
printf("\n\n請選擇:\n\n");
c=getchar(); //等待鍵盤輸入壹個字符,有回顯
}
if(!FLAG)
{
printf("\n\n記錄還沒有保存。\n現在保存嗎?(Y/N)\n\n\n");
c0=getch(); //等待鍵盤輸入壹個字符,但是無回顯
if(c0=='Y'||c0=='y') save();
printf("\n");
}
// system("PAUSE");
return 0;
}