c語言學生資訊管理系統(連結串列、檔案)
#include<stdio.h> /*呼叫標頭檔案*/
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<windows.h>
int del(); /*宣告使用的函式*/
void menu2();
void show_2();
void beifen();
void menu3();
void menu();
void show();
void WriteData_wb(struct student *head);
void WriteData_ab(struct student *head);
int modify1();
int zhenli();
struct student *ReadData(void);
#define LEN sizeof(struct student) /*將結構體的所佔空間有一串字母表示*/
#define N 2
struct student /*建立節點結構,表示每個學生的所含資訊*/
{
int number; /*學號*/
char name[5]; /*姓名*/
char grads[10]; /*班級*/
float score1; /*數學*/
float score2; /*c語言*/
char sex[5]; /*性別*/
char address[20]; /*所在城市*/
struct student*next; /*指向下一個節點的指標*/
};
int i; /*全域性變量表示連結串列長度*/
struct student* create(void) /*生成連結串列*/
{
struct student*head=NULL; /*初始化連結串列頭指標為空*/
struct student*end,*inew;
struct student*temp;
temp=ReadData();
i=0; /*初始化連結串列長度*/
end=inew=(struct student*)malloc(sizeof(struct student));
printf("如果要結束輸入,則請以0為學號,結束操作!\n");
printf("請輸入學生資訊\n");
printf("學號\n");
scanf("%d",&inew->number); /*作出是否繼續輸入的判斷*/
while(temp!=NULL)
{
if(inew->number==temp->number)
{
printf("輸入的學號已經存在\n\a"); /*確認資訊是否已經存在*/
system("pause");
menu();
}
temp=temp->next;
}
if(inew->number!=0)
{
printf("姓名\n"); /*輸出學生的相關資訊*/
scanf("%s",&inew->name);
printf("班級代號\n");
scanf("%s",&inew->grads);
printf("數學\n");
scanf("%f",&inew->score1);
printf("c語言\n");
scanf("%f",&inew->score2);
printf("性別\n");
scanf("%s",&inew->sex);
printf("所在城市\n");
scanf("%s",&inew->address);
}
while(inew->number!=0)
{
i++;
if(i==1)
{
inew->next=head; /*使得指向為空*/
end=inew; /*跟蹤新加入的節點*/
head=inew; /*頭指標指向首節點*/
}
else
{
inew->next=NULL; /*新節點的指標為空*/
end->next=inew; /*原來的尾節點指向新節點*/
end=inew; /*end指向新節點*/
}
inew=(struct student*)malloc(sizeof(struct student)); /*再次分配節點記憶體空間*/
printf("學號\n");
scanf("%d",&inew->number);
if(inew->number!=0)
{
printf("姓名\n");
scanf("%s",&inew->name);
printf("班級代號\n");
scanf("%s",&inew->grads);
printf("數學\n");
scanf("%f",&inew->score1);
printf("c語言\n");
scanf("%f",&inew->score2);
printf("性別\n");
scanf("%s",&inew->sex);
printf("所在城市\n");
scanf("%s",&inew->address);
}
}
free(inew); /*釋放沒有用到的空間*/
return head;
}
void menu() /*操作選單*/
{
char n;
system("cls"); /*清屏*/
printf("\n\n\n");
printf("歡迎光您!,學生管理系統!\t\n\n\n");
printf("\t\t\t║==========學生系統主目錄===========║\n");
printf("\t\t\t║===================================║\n");
printf("\t\t\t║ 0.exit 1.資料排序 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║===================================║\n");
printf("\t\t\t║ 2.查詢資訊 3.編輯資訊 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║===================================║\n");
printf("\t\t\t║ 4.顯示所有學生資訊 5.輸入資料 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║===================================║\n");
printf("\t\t\t║ 6.資料備份 ║\n");
printf("\t\t\t║===================================║\n");
printf("時間 : "); /*輸出系統時間*/
system("date /t");
printf(" ");
system("time /t");
printf("\n");
printf("\t\t\t\tchoose(0-6):【 】\b\b");
scanf("%c",&n);
switch(n) /*使用多路開關的switch語句*/
{ /*對應呼叫相關函式*/
case '0':
printf("\a");
exit (0);
case '1':
zhenli();
printf("\n\n資料已成功按照學號重新排列\n\n");
system("pause");
break;
case '2':
menu2();
break;
case '3':
menu3();
break;
case '4':
system("cls");
show();
break;
case '5':
WriteData_ab(create());
break;
case '6':
beifen();
break;
}
menu(); /*遞迴呼叫操作選單函式實現返回*/
}
/*2.查詢資訊二級目錄*/
void menu2()
{
int search1(); /*宣告將要呼叫的函式*/
int search2();
int search3();
int search4();
system("cls");
printf("\n\n\n");
printf("您現在的位置:主目錄->2.查詢資訊\n\n");
printf("\n\n\n");
printf("\t\t║==============歡迎進入學生系統==============║\n");
printf("\t\t║ ║\n");
printf("\t\t║================查詢資訊====================║\n");
printf("\t\t║ ║\n");
printf("\t\t║【1】 學號查詢 【2】 姓名查詢 ║\n");
printf("\t\t║ ║\n");
printf("\t\t║【3】 班級代號查詢 【4】 地址查詢 ║\n");
printf("\t\t║ ║\n");
printf("\t\t║ 【5】 返回主目錄 ║\n");
printf("\t\t║ ║\n");
printf("\t\t╰══════════════════════╯\n");
printf("◎請輸入功能前的序號進入相應的工具:【 】\b\b");
int a;
scanf("%d",&a);
while(a!=1&&a!=2&&a!=3&&a!=4&&a!=5) /*對輸入的數字進行初步判定*/
{
printf("無法識別的的字元\n");
printf("\a");
getchar();
printf("請重新輸入功能序號:【 】\b\b");
scanf("%d",&a);
}
switch(a) /*多路開關模式*/
{
case 1:
search1();
system("pause");
getchar();
break;
case 2:
search2();
system("pause");
getchar();
break;
case 3:
search3();
system("pause");
break;
case 4:
search4();
system("pause");
break;
case 5:
system("cls");
getchar();
menu();
break;
}
menu2(); /*遞迴呼叫原函式實現結束操作後的返回*/
}
int search1() /*學號查詢函式*/
{
struct student *pt; /*臨時指標*/
int a=0;
pt=ReadData(); /*開始讀取儲存在磁碟上的記錄資料的檔案*/
while(pt!=NULL) /*判斷檔案中是否有資料儲存*/
{ printf("請輸入你需要查詢的學號: ");
scanf("%d",&a);
if(pt->number==a) /*查詢對應的資訊並實現輸出*/
{
printf("學號: %d ",pt->number);
printf("姓名: %s ",pt->name);
printf("班級代號: %s ",pt->grads);
printf("數學: %3.2f ",pt->score1);
printf("c語言: %3.2f ",pt->score2);
printf("性別: %s ",pt->sex);
printf("所在城市: %s ",pt->address);
printf("\n\n");
}
pt=pt->next; /*指向下一個節點的指標實現迴圈查詢*/
}
if(pt==NULL)
{
printf("沒有記錄\n\a");
}
printf("\n");
return 0; /*結束標誌*/
}
int search2() /*姓名查詢函式*/
{
struct student *pt; /*臨時指標*/
char name[20]; /*用來儲存從鍵盤上輸入的字元*/
pt=ReadData(); /*讀取檔案*/
while(pt!=NULL) /*實現迴圈查詢資訊*/
{printf("請輸入你要查詢的姓名:");
scanf("%s",name);
if(strcmp(pt->name,name)==0)
{
printf("學號: %d ",pt->number);
printf("姓名: %s ",pt->name);
printf("班級代號: %s ",pt->grads);
printf("數學: %3.2f ",pt->score1);
printf("c語言: %3.2f ",pt->score2);
printf("性別: %s ",pt->sex);
printf("所在城市: %s ",pt->address);
printf("\n\n");
}
pt=pt->next; /*節點指標的迴圈操作*/
}
printf("\n");
if(pt==NULL)
{
printf("沒有記錄\n\n\a");
}
return 0;
}
int search3() /*班級代號查詢函式*/
{
struct student *pt; /*臨時指標*/
char g[6]; /*儲存從鍵盤上輸入的資訊*/
pt=ReadData(); /*讀取存有資訊的檔案*/
while(pt!=NULL)
{printf("請輸入你要查詢的班級:");
scanf("%s",g);
if(strcmp(pt->grads,g)==0) /*判斷瀏覽到資訊是否合格並輸入*/
{
printf("學號: %d ",pt->number);
printf("姓名: %s ",pt->name);
printf("班級代號: %s ",pt->grads);
printf("數學: %3.2f ",pt->score1);
printf("c語言: %3.2f ",pt->score2);
printf("性別: %s ",pt->sex);
printf("所在城市: %s ",pt->address);
printf("\n\n");
}
pt=pt->next;
}
printf("\n");
if(pt==NULL)
{
printf("沒有記錄\n\n\a");
}
return 0;
}
int search4() /*地址查詢函式*/
{
struct student *pt;
char d[50]; /*儲存從鍵盤上輸入的字元*/
pt=ReadData(); /*讀取檔案*/
while(pt!=NULL)
{printf("請輸入你要查詢的地址:");
scanf("%s",d);
if(strcmp(pt->address,d)==0) /*遍歷查詢匹配項並輸出*/
{
printf("學號: %d ",pt->number);
printf("姓名: %s ",pt->name);
printf("班級代號: %s ",pt->grads);
printf("數學: %3.2f ",pt->score1);
printf("c語言: %3.2f ",pt->score2);
printf("性別: %s ",pt->sex);
printf("所在城市:%s ",pt->address);
printf("\n\n");
}
pt=pt->next; /*迴圈操作*/
}
printf("\n");
if(pt==NULL)
{
printf("沒有記錄\a\n\n");
}
return 0; /*結束標誌*/
}
void menu3() /*修改資訊函式*/
{
system("cls");
printf("\n\n\n"); /*顯示介面*/
printf("您現在的位置:主目錄->3.修改資訊\n\n");
printf("\n\n\n");
printf("\t\t║=================歡迎進入學生系統===========║\n");
printf("\t\t║ ║\n");
printf("\t\t║================編輯資訊====================║\n");
printf("\t\t║ ║\n");
printf("\t\t║ 【1】 刪除記錄 【2】 插入資料 ║\n");
printf("\t\t║ ║\n");
printf("\t\t║ 【3】 修改記錄 【4】 返回主目錄 ║\n");
printf("\t\t║ ║\n");
printf("\t\t╰══════════════════════╯\n");
printf("請輸入功能序號:【 】\b\b");
getchar();
char a; /*選擇操作*/
scanf("%c",&a);
while(a!='1'&&a!='2'&&a!='3'&&a!='4') /*判斷是否進行下一步的操作*/
{
printf("無法識別的字元!\n");
printf("\a");
printf("請重新輸入功能序號:【 】\b\b");
scanf("%c",&a);
}
switch(a) /*多路開關*/
{
case '1':
show_2();
del();
system("pause");
menu3();
break;
case '2':
WriteData_ab(create());
system("pause");
menu3();
break;
case '3':
modify1();
system("pause");
menu3();
break;
case '4':
system("cls");
getchar();
menu();
break;
}
}
/*資料排序*/
int zhenli() /*按照學號從小到大排序*/
{
printf("按學號排序\n");
struct student *head;
struct student *first;
struct student *tail;
struct student *p_min;
struct student *min;
struct student *p;
head=ReadData();
first=NULL; /*初始化為空指標*/
while(head!=NULL)
{
for(p=head,min=head;p->next!=NULL;p=p->next)
{
if(p->next->number<min->number)
{
p_min=p;
min=p->next;
}
}
if(first==NULL)
{
first=min;
tail=min;
}
else
{
tail->next=min;
tail=min;
}
if(min==head)
{
head=head->next;
}
else
{
p_min->next=min->next;
}
}
if(first!=NULL)
{
tail->next=NULL;
}
head=first;
WriteData_wb(head);
return 0;
}
int modify1() /*修改記錄的函式*/
{
show_2();
struct student *pt1; /*定義臨時指標*/
pt1=ReadData(); /*讀取檔案資訊*/
printf("請選擇以何種方式刪除記錄(1.學號/2.姓名)");
getchar();
char xinxi;
scanf("%c",&xinxi);
if(xinxi=='1')
{
int num;
printf("請輸入你要修改的學號資訊: ");
scanf("%d",&num);
while(pt1!=NULL)
{
if(pt1->number==num) /*遍歷查詢匹配的資訊*/
{
printf("1.學號: %d ",pt1->number);
printf("2.姓名: %s ",pt1->name);
printf("3.班級代號: %s ",pt1->grads);
printf("4.數學: %3.2f ",pt1->score1);
printf("5.c語言: %3.2f ",pt1->score2);
printf("6.性別: %s ",pt1->sex);
printf("7.所在城市: %s ",pt1->address);
printf("\n\a");
printf("請確認是否修改(1.y/2.n)\n"); /*判斷是否進行下一步操作*/
int ch;
scanf("%d",&ch);
if(ch==1);
else
{
printf("\a");
menu3();
}
int a;
printf("請選擇需要修改的專案(1~~7)\n");
scanf("%d",&a);
switch(a) /*多路開關選擇性呼叫函式*/
{
case 1:
printf("學號\n");
scanf("%d",&pt1->number);
break;
case 2:
printf("姓名\n");
scanf("%s",pt1->name);
break;
case 3:
printf("班級代號\n");
scanf("%s",pt1->grads);
break;
case 4:
printf("數學\n");
scanf("%f",pt1->score1);
break;
case 5:
printf("c語言\n");
scanf("%f",pt1->score2);
break;
case 6:
printf("性別\n");
scanf("%s",pt1->sex);
break;
case 7:
printf("所在城市\n");
scanf("%s",pt1->address);
break;
default:
printf("輸入錯誤\a\n");
continue;
}
printf("1.學號:%d ",pt1->number); /*輸出修改後的資料資訊*/
printf("2.姓名:%s ",pt1->name);
printf("3.班級代號:%s ",pt1->grads);
printf("4.數學:%3.2f ",pt1->score1);
printf("5.c語言:%3.2f ",pt1->score2);
printf("6.性別:%s ",pt1->sex);
printf("7.所在城市:%s ",pt1->address);
printf("\n\n已成功修改指定資料\n\n");
WriteData_wb(pt1); /*寫入磁碟檔案*/
break; /*跳出本迴圈*/
}
pt1=pt1->next;
}
if(pt1==NULL)
{
printf("沒有儲存你要刪除的資料!\n");
printf("\a");
}
}
else if(xinxi=='2')
{
char name[10];
printf("請輸入你要修改的學生姓名: ");
scanf("%s",&name);
while(pt1!=NULL)
{
if(strcmp(pt1->name,name)==0) /*遍歷查詢匹配的資訊*/
{
printf("1.學號: %d ",pt1->number);
printf("2.姓名: %s ",pt1->name);
printf("3.班級代號: %s ",pt1->grads);
printf("4.數學: %3.2f ",pt1->score1);
printf("5.c語言: %3.2f ",pt1->score2);
printf("6.性別: %s ",pt1->sex);
printf("7.所在城市: %s ",pt1->address);
printf("\n\a");
printf("請確認是否修改(1.y/2.n)\n"); /*判斷是否進行下一步操作*/
int ch;
scanf("%d",&ch);
if(ch==1);
else
{
printf("\a");
menu3();
}
int a;
printf("請選擇需要修改的專案(1~~7)\n");
scanf("%d",&a);
switch(a) /*多路開關選擇性呼叫函式*/
{
case 1:
printf("學號\n");
scanf("%d",&pt1->number);
break;
case 2:
printf("姓名\n");
scanf("%s",pt1->name);
break;
case 3:
printf("班級代號\n");
scanf("%s",pt1->grads);
break;
case 4:
printf("數學\n");
scanf("%f",pt1->score1);
break;
case 5:
printf("c語言\n");
scanf("%f",pt1->score2);
break;
case 6:
printf("性別\n");
scanf("%s",pt1->sex);
break;
case 7:
printf("所在城市\n");
scanf("%s",pt1->address);
break;
default:
printf("輸入錯誤\a\n");
continue;
}
printf("1.學號:%d ",pt1->number); /*輸出修改後的資料資訊*/
printf("2.姓名:%s ",pt1->name);
printf("3.班級代號:%s ",pt1->grads);
printf("4.數學:%3.2f ",pt1->score1);
printf("5.c語言:%3.2f ",pt1->score2);
printf("6.性別:%s ",pt1->sex);
printf("7.所在城市:%s ",pt1->address);
printf("\n\n已成功修改指定資料\n\n");
WriteData_wb(pt1); /*寫入磁碟檔案*/
break; /*跳出本迴圈*/
}
pt1=pt1->next;
}
if(pt1==NULL)
{
printf("沒有儲存你要刪除的資料!\n");
printf("\a");
}
}
return 0;
}
/*資料存檔(wb)*/
void WriteData_wb(struct student *head)
{
FILE *fp;
struct student *p;
if((fp=fopen("name", "wb+"))==NULL)
printf("\a error! Can not open the file!");
p=head;
while(p!=NULL)
{
if(fwrite(p,LEN,1,fp)!=1)
{
printf("寫入資料出錯\n");
fclose(fp);
return;
}
p=p->next;
}
fclose(fp);
}
/*資料存檔(ab)*//*在文字末尾新增*/
void WriteData_ab(struct student *head)
{
FILE *fp;
struct student *p;
if((fp = fopen("name", "ab+"))==NULL)
printf("\a error! Can not open the file!");
p=head;
while(p!=NULL)
{
if(fwrite(p,LEN,1,fp)!=1)
{
printf("寫入資料出錯\n");
fclose(fp);
return;
}
p=p->next;
}
fclose(fp);
}
/*讀取資料*/
/*讀取資料檔案儲存到連結串列中 ,返回指向此連結串列頭指標*/
struct student *ReadData(void)
{
struct student *head=NULL;
struct student *p1, *p2;
FILE *fp;
if((fp=fopen("name","rb+"))==NULL)
{
printf("開啟檔案出錯\n");
system("pause");
fp=fopen("name","wb+");
}
while(!feof(fp))
{
if((p1=(struct student*)malloc(LEN))==NULL) /*判斷檔案是否可以開啟*/
{
printf("記憶體申請出錯\n");
fclose(fp);
exit(0);
}
if(fread(p1,LEN,1,fp)!=1)
{
free(p1);
break;
}
if(head==NULL)
head=p2=p1;
else
{
p2->next=p1;
p2=p1;
}
}
fclose(fp);
return (head);
}
void show() /*顯示資訊函式*/
{
struct student *temp;
printf("\n");
printf("所有資訊如下:\n\n");
temp=ReadData(); /*讀取檔案資訊*/
while(temp!=NULL)
{
printf("學號: %d ",temp->number);
printf("姓名: %s ",temp->name);
printf("班級代號: %s ",temp->grads);
printf("數學: %3.2f ",temp->score1);
printf("c語言: %3.2f ",temp->score2);
printf("性別: %s ",temp->sex);
printf("所在城市:%s ",temp->address);
printf("\n\n");
temp=temp->next;
}
system("pause");
menu();
}
void show_2() /*顯示資訊函式*/
{
struct student *temp;
printf("\n");
printf("所有資訊如下:\n\n");
temp=ReadData(); /*讀取檔案資訊*/
while(temp!=NULL)
{
printf("學號: %d ",temp->number);
printf("姓名: %s ",temp->name);
printf("班級代號: %s ",temp->grads);
printf("數學: %3.2f ",temp->score1);
printf("c語言: %3.2f ",temp->score2);
printf("性別: %s ",temp->sex);
printf("所在城市:%s ",temp->address);
printf("\n\n");
temp=temp->next;
}
}
int del() /*刪除操作*/
{
struct student *temp,*pre; /*定義要刪除的節點指標和刪除前的節點指標*/
temp=ReadData(); /*刪除的節點開始讀檔案*/
if(temp==NULL) /*判斷檔案是否為空*/
{
printf("沒有記錄\a\n\n");
system("pause");
menu3();
}
pre=temp;
printf("請選擇以何種方式刪除記錄(1.學號/2.姓名/3.返回)");/*提示資訊*/
getchar();
char xinxi;
scanf("%c",&xinxi);
if(xinxi=='1')
{
int a;
printf("請輸入你需要刪除的學號: ");
scanf("%d",&a);
/*跟隨刪除的節點指標*/
while(temp!=NULL)
{
if(temp->number==a) /*遍歷查詢匹配的資訊並輸出*/
{
printf("已經找到學生的資訊\n");
printf("學號: %d ",temp->number);
printf("姓名: %s ",temp->name);
printf("班級代號: %s ",temp->grads);
printf("數學: %3.2f ",temp->score1);
printf("c語言: %3.2f ",temp->score2);
printf("性別: %s ",temp->sex);
printf("所在城市: %s ",temp->address);
printf("\n\n");
printf("是否刪除該學生資訊:(1.y/2.n)\n"); /*判斷是否繼續下一步操作*/
int ch;
scanf("%d",&ch);
if(ch==1)
{
temp=temp->next; /*指向刪除節點的後一個指標的節點*/
pre->next=temp; /*合併刪除節點兩邊的節點*/
WriteData_wb(temp); /*將刪除節點後的資訊存入到磁碟檔案*/
free(temp); /*釋放掉要刪除節點的記憶體空間*/
printf("成功修改\n");
}
else
{
printf("失敗\n\t\t\a");
system("pause");
menu3();
}
printf("返回");
break;
}
else{
printf("沒有找到匹配的資料\n\a");
}
temp=temp->next; /*迴圈操作*/
}
}
else
if(xinxi=='2')
{
char name[5];
printf("你想刪除學生的姓名:\n");
scanf("%s",name);
do
{
if(strcmp(temp->name,name)==0) /*遍歷查詢匹配的資訊並輸出*/
{
printf("已經找到學生的資訊\n");
printf("學號: %d ",temp->number);
printf("姓名: %s ",temp->name);
printf("班級代號: %s ",temp->grads);
printf("數學: %3.2f ",temp->score1);
printf("c語言: %3.2f ",temp->score2);
printf("性別: %s ",temp->sex);
printf("所在城市: %s ",temp->address);
printf("\n\n");
printf("是否刪除該學生資訊:(1.y/2.n)\n"); /*判斷是否繼續下一步操作*/
int ch;
scanf("%d",&ch);
if(ch==1)
{
temp=temp->next; /*指向刪除節點的後一個指標的節點*/
pre->next=temp; /*合併刪除節點兩邊的節點*/
WriteData_wb(temp); /*將刪除節點後的資訊存入到磁碟檔案*/
free(temp); /*釋放掉要刪除節點的記憶體空間*/
printf("成功修改\n");
}
else
{
printf("失敗\n\t\t\a");
system("pause");
menu3();
}
printf("返回");
break;
}
else
{
printf("沒有找到匹配的資料\n\a");
}
temp=temp->next; /*迴圈操作*/
}while(temp!=NULL);
}
if(xinxi=='3')
{
menu3();
}
else
{
printf("\a\n");
del();
}
getchar();
return 0;
}
void main() /*主調函式*/
{
struct student *pt; /*定義頭節點*/
pt=ReadData(); /*頭結點呼叫磁碟檔案*/
if(pt!=NULL) /*判斷讀取的檔案是否存在資料*/
{
show(); /*不為空則輸出已有資訊*/
}
else
if(pt==NULL)
{
menu(); /*為空就進入操作選單*/
}
}
void beifen()
{
FILE*fp;
struct student *temp;
temp=ReadData();
char name[50];
printf("請輸入備份檔名");
scanf("%s",name);
if((fp=fopen(name,"wb+"))==NULL)
{
printf("檔案開啟失敗\a");
}
while(temp!=NULL)
{
if(fwrite(temp,LEN,1,fp)!=1)
{
printf("寫入資料出錯\n");
fclose(fp);
return;
}
temp=temp->next;
}
fclose(fp);
printf("備份成功!\n\a");
system("pause");
}