自寫資訊管理系統——C實現
資訊管理系統
簡介:
該管理系統分為三個許可權:學生,老師,管理員
用雙向連結串列實現,檔案儲存,有賬號密碼功能。
密碼實現MD5加密,較難破解
實現了連結串列新增,查詢,排序,刪除等基本操作
管理員能夠管理學生和老師的密碼和賬號,進行一些簡單的新增,刪除,更改操作。老師具有資訊錄入 ,檢視,修改,查詢,刪除,排序許可權。而學生有資訊檢視,查詢和排序許可權。管理員具有資訊錄入 ,檢視,修改,查詢,刪除,排序和老師學生資訊管理許可權。對於密碼,這裡採用及其難以破解的MD5密碼加密,根據MD5原始碼進行改編,最終得到MD5的函式,對錄入的密碼進行加密操作,然後儲存到檔案中,這樣就保證了即使知道檔案並開啟檔案,也無法破解其密碼!
共分為6個檔案
5個.cpp檔案 1個.h檔案
下面上程式碼 :
mian.cpp:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#include<io.h>
#define LEN 100
#define PAGE 3 //分頁輸出時,每頁的學生個數
void admin();
int menu_admin();
void change_change_order_tea();
int menu_change_order_tea();
void change_delete_order_tea();
void teacher();
int menu_tea();
bool judge_tea();
int read_file_order_tea();
void change_change_order_stu();
int menu_change_order_stu();
void change_delete_order_stu();
void student();
int menu_stu();
bool judge_stu();
int read_file_order_stu();
bool judge_admin();
void change_order_admin();
int menu();
int pmenu_search();
int read_file();
void pdisplay();
void pdisplay_sort();
int psearch_mname();
int psearch_schoolnum();
int psearch_phone();
int psearch_sex();
int psearch_age();
int delete_pmenu_search();
int delete_psearch_schoolnum();
int delete_psearch_mname();
int delete_psearch_phone();
int delete_psearch_age();
int delete_psearch_sex();
int change_pmenu_search();
int change_psearch_schoolnum();
int change_psearch_mname();
int change_psearch_phone();
int change_psearch_age();
int change_psearch_sex();
int psort_menu();
void psort_age();
void psort_schoolnum();
void save_order_tea();
void save();
void save_order_stu();
typedef struct {
char mname[9];
char schoolnum[15];
char sex[3];
int age;
char address[20];
char phone[15];
}Node;
typedef struct student
{
Node information;
struct student *next;
struct student *last;
}STUDENT;
typedef struct
{
char username[100];
char password[100];
}Node_order_tea;
typedef struct order_tea
{
Node_order_tea information;
struct order_tea *next;
struct order_tea *last;
}ORDER_TEA;
typedef struct
{
char username[100];
char password[100];
}Node_order_stu;
typedef struct order_stu
{
Node_order_stu information;
struct order_stu *next;
struct order_stu *last;
}ORDER_STU;
int num=0; //檔案中總的學生資訊個數
STUDENT *head=NULL,*iend,*inew;
FILE *fp; //檔案指標
int num_order_tea=0; //檔案中總的學生資訊個數
ORDER_TEA *head_order_tea=NULL,*iend_order_tea,*inew_order_tea;
FILE *fp_order_tea;
int num_order_stu=0; //檔案中總的學生資訊個數
ORDER_STU *head_order_stu=NULL,*iend_order_stu,*inew_order_stu;
FILE *fp_order_stu;
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/**********************新加入*****************************/
int main()
{
int chioce;
do
{
printf("\n\t\t********************************\n");
printf("\t\t* 1.老師 *\n");
printf("\t\t* 2.學生 *\n");
printf("\t\t* 3.管理員 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*********************************\n");
printf("\t\t請選擇登陸身份:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
teacher();
break;
case 2:
student();
break;
case 3:
admin();
default:
break;
}
}while(chioce!=0);
return 0;
}
#include"head.h"
/********************獲取檔名;讀取內容;給num,fp,head,flieopenname賦值;建立連結串列***********************/
//開啟檔案,並讀取檔案
int read_file()
{
int i;
int fno,fsize;
if((fp=fopen("student_system.txt","rt"))==NULL)//判斷檔案是否存在,若存在開啟
{ //否則詢問是否繼續開啟
printf("\n庫檔案不存在!\n");
return 0;
}
rewind(fp); //使檔案內部指標移動到檔案的開始位置
fno=fileno(fp); //獲取檔案描述字
fsize=filelength(fno); //計算檔案大小,以位元組為單位
num=fsize/sizeof(Node); //計算檔案包含的學生資訊數目
iend=inew=(STUDENT *)malloc(sizeof(STUDENT));//申請動態空間
fread(inew,sizeof(Node),1,fp); //以Node(結構體)的空間大小讀資料
for(i=1;i<=num;i++) //利用for迴圈建立連結串列,並把資料儲存到其中
{
if(i==1) //第一個節點的建立
{
inew->next=head;
inew->last=NULL; //雙向連結串列
iend=inew;
head=inew;
}
else
{
inew->next=NULL;
inew->last=iend;
iend->next=inew;
iend =inew;
}
inew=(STUDENT *)malloc(sizeof(STUDENT));
fread(inew,sizeof(Node),1,fp);
}
free(inew);//釋放最後一個沒有儲存資料的節點
fclose(fp);//關閉檔案
return num;
}
/****************************輸入函式*******************/
STUDENT *pinput()
{
char ch;
if(num==0)//判斷是否是第一次錄入
{
iend=inew=(STUDENT *)malloc(sizeof(STUDENT));//申請空間
inputone(inew); //錄入資訊
while(1)
{
num++;
if(num==1) //錄入第一個學生資訊時,第一個節點的指標指向
{
inew->next=NULL;
inew->last=NULL;
iend =inew;
head =inew;
}
else //在第一個節點的存在下,進行其他節點的錄入
{
inew->next=NULL; //新建立節點next指向NULL
inew->last=iend; //新建立節點last指向上一個節點
iend->next=inew; //第一個next->下一個節點
iend =inew; //讓iend指向最後一個節點
}
inew=(STUDENT *)malloc(sizeof(STUDENT));
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n') break;//判斷是否跳出迴圈
inputone(inew);
}
free(inew); //釋放未儲存資料的節點
return head;
}
else//非第一次錄入時
{
while(1)//進行迴圈輸入,並進行判斷,是否跳出迴圈
{
inew=(STUDENT *)malloc(sizeof(STUDENT));
getch();
inputone(inew);
num++;
inew->next=NULL; //新建立節點next指向NULL
inew->last=iend; //新建立節點last指向上一個節點
iend->next=inew; //第一個next->下一個節點
iend =inew; //讓iend指向最後一個節點
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n')
break;
}
return head;
}
}
void inputone(STUDENT *temp)
{
printf("************************\n");
printf("請輸入學生的姓名:");
scanf("%s",inew->information.mname);
printf("請輸入學生的學號:");
scanf("%s",inew->information.schoolnum);
printf("請輸入學生的性別(男-M 女-F):");
scanf("%s",inew->information.sex);
printf("請輸入學生的年齡:");
scanf("%d",&inew->information.age);
printf("請輸入學生的家庭住址:");
scanf("%s",inew->information.address);
printf("請輸入學生的電話號碼:");
scanf("%s",inew->information.phone);
}
/****************************輸出函式*******************/
void displayone(STUDENT *temp) //為簡化程式- 單個輸出函式,用於呼叫!
{
printf("**********************************\n");
printf("姓名:%s\n",temp->information.mname);
printf("學號:%s\n",temp->information.schoolnum);
printf("性別:%s\n",temp->information.sex);
printf("年齡:%d\n",temp->information.age);
printf("家庭住址:%s\n",temp->information.address);
printf("電話號碼:%s\n",temp->information.phone);
printf("===========================\n");
}
/**************************以head為起始輸出連結串列******************************/
void pdisplay()//核心思想:對連結串列進行操作,然後利用while迴圈輸出
{
STUDENT *temp,*temp1;
int page=1,lastnum=num%PAGE,stu=0,i,page1;
char ch;
int choice;
if(head==NULL)//判斷檔案中是否有資料
{
printf("檔案中沒有資料!!\n");
getch();
return;
}
temp=head;
page1=num/PAGE+1;//進行頁數的初始化
if(lastnum==0)//判斷最後一頁的資料數
{
lastnum=PAGE;
page1=page1-1;
}
while(1)//保留最後節點的指標
{
if(temp->next==NULL)
{
temp1=temp;
break;
}
temp=temp->next;
}
temp=head;
rewind(fp);
loop: printf("----------------------------第%d頁-----------------------------\n",page);
while(temp!=NULL)//利用while 結構進行輸出 知道到最後節點
{
displayone(temp);
temp=temp->next;
stu++;
if(stu==PAGE)//一頁輸出完後進行選擇,對其連結串列進行操作
{
printf("4---首頁 <--上一頁--1 3--下一頁--> 尾頁---6 \n");
scanf("%d",&choice);
switch(choice)
{
case 1://上一頁,清屏 ,對其連結串列進行操作
for(i=1;i<=PAGE+stu;i++)
{
temp=temp->last;
if(temp==head)
{
temp=head;
page=1;
break;
}
}
if(temp!=head)
page--;
stu=0;
system("cls");
goto loop;
break;
case 4://第一頁,清屏 ,把head值賦給temp
system("cls");
temp=head;
stu=0;
page=1;
goto loop;
break;
case 6://最後一頁,清屏 ,對連結串列進行操作,找到相應連結串列值賦給temp
system("cls");
temp=temp1;
for(i=1;i<=lastnum-1;i++)
{
temp=temp->last;
if(temp==head)
{
temp=head;
page=1;
break;
}
}
if(temp!=head)
page=page1;
goto loop;
break;
case 3://下一頁,清屏 繼續輸出,
system("cls");
stu=0;
page++;
goto loop;
break;
}
stu=0;
}
}
if(temp==NULL)
{
printf("\n-------------已到尾頁,是否返回首頁?(是-Y 否-N):---------------");
scanf("\n%c",&ch);
if(toupper(ch)=='Y')
{
temp= head;
page=1;
stu=0;
system("cls");
goto loop;
}
}
getch();
}
/***************************加上提示語句*以head為起始輸出連結串列**********************************/
void pdisplay_sort()
{ //提示語句,表示已經進行排序,然後呼叫輸出函式
printf("\n資訊已經進行了排序,排序後資訊如下:\n");
pdisplay();
}
/****************************搜尋函式***head****************/
//基本思路:從第一個資料節點開始進行遍歷,知道找到相應資訊為止
//遍歷: while迴圈
//資訊比較:if()條件判斷語句 及用break;跳出迴圈
//進行顯示
//若未找到,輸出提示!
int pmenu_search()
{
int chioce;
do//利用switch選擇結構和do-while迴圈,建立子選單!
{
printf("\n");
printf("\t\t********************************\n");
printf("\t\t* 1.按姓名查詢 *\n");
printf("\t\t* 2.按學號查詢 *\n");
printf("\t\t* 3.按電話號碼查詢 *\n");
printf("\t\t* 4.按性別查詢 *\n");
printf("\t\t* 5.按年齡查詢 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
psearch_mname(); //呼叫按姓名查詢函式
getch();
break;
case 2:
psearch_schoolnum(); //呼叫按學號查詢函式
getch();
break;
case 3:
psearch_phone(); //呼叫按電話號碼查詢函式
getch();
break;
case 4:
psearch_sex(); //呼叫按性別查詢函式
getch();
break;
case 5:
psearch_age(); //呼叫按年齡查詢函式
getch();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
int psearch_schoolnum()
{
char schoolnum1[15];
int x=0;
STUDENT *temp;
temp=head;
printf("請輸入學生學號:");
scanf("%s",schoolnum1);
while(temp!=NULL) //利用while 函式對連結串列進行遍歷,並查詢
{
if(!strcmp(schoolnum1,temp->information.schoolnum))//利用字串處理函式進行比較
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
break; //輸出並跳出迴圈
}
x++;
temp=temp->next;
}
if(x==num)//判斷是否找到 ,如果未找到,輸出提示!
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
return x;
}
int psearch_mname()
{
char mname1[9];
int x=0;
STUDENT *temp;
temp=head;
printf("請輸入學生姓名:");
scanf("%s",mname1);
while(temp!=NULL)
{
if(!strcmp(mname1,temp->information.mname))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
break;
}
x++;
temp=temp->next;
}
if(x==num)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
return x;
}
int psearch_phone()
{
char phone1[15];
int x=0;
STUDENT *temp;
temp=head;
printf("請輸入學生電話:");
scanf("%s",phone1);
while(temp!=NULL)
{
if(!strcmp(phone1,temp->information.phone))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
break;
}
x++;
temp=temp->next;
}
if(x==num)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
return x;
}
int psearch_sex()
{
char sex1[15];
int x=0;
STUDENT *temp;
temp=head;
printf("請輸入學生性別:");
scanf("%s",sex1);
while(temp!=NULL)
{
if(!strcmp(sex1,temp->information.sex))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
}
x++;
temp=temp->next;
}
if(x==num)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
return x;
}
int psearch_age()
{
STUDENT *temp;
temp=head;
int age,x=0;
printf("請輸入學生年齡:");
scanf("%d",&age);
while(temp!=NULL)
{
if(age==temp->information.age)
{
printf("姓名:%s\n",temp->information.mname);
printf("學號:%s\n",temp->information.schoolnum);
printf("性別:%s\n",temp->information.sex);
printf("年齡:%d\n",temp->information.age);
printf("家庭住址:%s\n",temp->information.address);
printf("電話號碼:%s\n",temp->information.phone);
printf("===========================\n");
x++;
}
temp=temp->next;
}
if(x==num)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
return x;
}
/****************************刪除函式 head*******************/
//基本思路:從第一個資料節點開始進行遍歷,知道找到相應資訊為止
//而後把其節點刪除,把指標連線到下一節點上
//若未找到,輸出提示!
int delete_pmenu_search()
{
int chioce;
do
{
printf("\n");
printf("\t\t********************************\n");
printf("\t\t* 1.按姓名檢索 *\n");
printf("\t\t* 2.按學號檢索 *\n");
printf("\t\t* 3.按電話號碼檢索 *\n");
printf("\t\t* 4.按性別檢索 *\n");
printf("\t\t* 5.按年齡檢索 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
delete_psearch_mname();
getch();
break;
case 2:
delete_psearch_schoolnum();
getch();
break;
case 3:
delete_psearch_phone();
getch();
break;
case 4:
delete_psearch_sex();
getch();
break;
case 5:
delete_psearch_age();
getch();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
int delete_psearch_schoolnum()
{
char schoolnum1[15];
char ch;
int i;
int x=0,live=0;
STUDENT *temp,*pPre,*pTemp;
temp =head;
pTemp=head;
pPre =head;
printf("請輸入學生學號:");
scanf("%s",schoolnum1);
while(temp!=NULL)//利用while先遍歷搜尋
{
x++;
if(!strcmp(schoolnum1,temp->information.schoolnum))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否刪除資料?(刪除-Y,放棄刪除-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
if(x==1)//判斷是否是第一個資料
{
head=pTemp->next;
}
else //x為計數器,找出其節點的上一個和下一個節點
{ //並連線兩個節點 ,也可以利用雙向連結串列進行連線
for(i=1;i<x;i++) //若建立雙向連結串列
{ //temp->last->next=temp->next;
pPre=pTemp;
pTemp=pTemp->next;
}
pPre->next=pTemp->next;
}
free(pTemp); //釋放刪除了的節點空間
num--; //num代表總的學生資料數,資料數減一
printf("資料已刪除!");
}
return x;
}
x=0;
}
int delete_psearch_mname()
{
char mname1[9];
char ch;
int x=0,i,live=0;
STUDENT *temp,*pPre,*pTemp;
temp =head;
pTemp=head;
pPre =pTemp;
printf("請輸入學生姓名:");
scanf("%s",mname1);
while(temp!=NULL)
{
x++;
if(!strcmp(mname1,temp->information.mname))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否刪除資料?(刪除-Y,放棄刪除-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
if(x==1)
{
head=pTemp->next;
}
else
{
for(i=1;i<x;i++)
{
pPre=pTemp;
pTemp=pTemp->next;
}
pPre->next=pTemp->next;
}
free(pTemp);
num--;
printf("資料已刪除!");
}
return x;
}
x=0;
}
int delete_psearch_phone()
{
char phone1[15];
char ch;
int x=0,i,live=0;
STUDENT *temp,*pPre,*pTemp;
temp =head;
pTemp=head;
pPre =pTemp;
printf("請輸入學生電話:");
scanf("%s",phone1);
while(temp!=NULL)
{
x++;
if(!strcmp(phone1,temp->information.phone))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否刪除資料?(刪除-Y,放棄刪除-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
if(x==1)
{
head=pTemp->next;
}
else
{
for(i=1;i<x;i++)
{
pPre=pTemp;
pTemp=pTemp->next;
}
pPre->next=pTemp->next;
}
free(pTemp);
num--;
printf("資料已刪除!");
}
return x;
}
x=0;
}
int delete_psearch_sex()
{
char sex1[15];
int x=0,live=0;
STUDENT *temp;
temp=head;
printf("請輸入學生性別:");
scanf("%s",sex1);
while(temp!=NULL)
{
if(!strcmp(sex1,temp->information.sex))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
}
x++;
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("請確定您所需要刪除的學生資訊!");
getch();
delete_pmenu_search();
return x;
}
}
int delete_psearch_age()
{
STUDENT *temp;
temp=head;
int age,x=0,live=0;
printf("請輸入學生年齡:");
scanf("%d",&age);
while(temp!=NULL)
{
if(age==temp->information.age)
{
printf("姓名:%s\n",temp->information.mname);
printf("學號:%s\n",temp->information.schoolnum);
printf("性別:%s\n",temp->information.sex);
printf("年齡:%d\n",temp->information.age);
printf("家庭住址:%s\n",temp->information.address);
printf("電話號碼:%s\n",temp->information.phone);
printf("===========================\n");
live=1;
x++;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("請確定您所需要刪除的學生資訊!");
getch();
delete_pmenu_search();
return x;
}
}
/***************************修改函式* head******************/
//基本思路:從第一個資料節點開始進行遍歷,知道找到相應資訊為止
//而後把其節點重新錄入,覆蓋原節點!
//若未找到,輸出提示!
int change_one(STUDENT *pTemp)//利用單個函式簡化函式
{
printf("請重新錄入!");
printf("************************\n");
printf("請輸入學生的姓名:");
scanf("%s",pTemp->information.mname);
printf("請輸入學生的學號:");
scanf("%s",pTemp->information.schoolnum);
printf("請輸入學生的性別(男-M 女-F):");
scanf("%s",pTemp->information.sex);
printf("請輸入學生的年齡:");
scanf("%d",&pTemp->information.age);
printf("請輸入學生的家庭住址:");
scanf("%s",pTemp->information.address);
printf("請輸入學生的電話號碼:");
scanf("%s",pTemp->information.phone);
return 0;
}
int change_pmenu_search()
{
int chioce;
do
{
printf("\n");
printf("\t\t********************************\n");
printf("\t\t* 1.按姓名檢索 *\n");
printf("\t\t* 2.按學號檢索 *\n");
printf("\t\t* 3.按電話號碼檢索 *\n");
printf("\t\t* 4.按性別檢索 *\n");
printf("\t\t* 5.按年齡檢索 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
change_psearch_mname();
getch();
break;
case 2:
change_psearch_schoolnum();
getch();
break;
case 3:
change_psearch_phone();
getch();
break;
case 4:
change_psearch_sex();
getch();
break;
case 5:
change_psearch_age();
getch();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
int change_psearch_schoolnum()
{
char schoolnum1[15];
char ch;
int live=0;
STUDENT *temp;
temp=head;
printf("請輸入學生學號:");
scanf("%s",schoolnum1);
while(temp!=NULL)
{
if(!strcmp(schoolnum1,temp->information.schoolnum))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否修改資料?(修改-Y,放棄修改-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
change_one(temp);
printf("資料修改完成!");
}
return 0;
}
}
int change_psearch_mname()
{
char mname1[9];
char ch;
int live=0;
STUDENT *temp;
temp=head;
printf("請輸入學生姓名:");
scanf("%s",mname1);
while(temp!=NULL)
{
if(!strcmp(mname1,temp->information.mname))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否修改資料?(修改-Y,放棄修改-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
change_one(temp);
printf("資料修改完成!");
}
return 0;
}
}
int change_psearch_phone()
{
char phone1[15];
char ch;
int live=0;
STUDENT *temp;
temp =head;
printf("請輸入學生電話:");
scanf("%s",phone1);
while(temp!=NULL)
{
if(!strcmp(phone1,temp->information.phone))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
break;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("是否修改資料?(修改-Y,放棄修改-N)");
scanf("\n%c",&ch);
if(ch=='y'||ch=='Y')
{
change_one(temp);
printf("資料修改完成!");
}
return 0;
}
}
int change_psearch_sex()
{
char sex1[15];
int x=0,live=0;
STUDENT *temp;
temp=head;
printf("請輸入學生性別:");
scanf("%s",sex1);
while(temp!=NULL)
{
if(!strcmp(sex1,temp->information.sex))
{
printf("查詢結果如下:\n");
printf("=============================\n");
printf("\t姓名:%s\n",temp->information.mname);
printf("\t學號:%s\n",temp->information.schoolnum);
printf("\t性別:%s\n",temp->information.sex);
printf("\t年齡:%d\n",temp->information.age);
printf("\t家庭住址:%s\n",temp->information.address);
printf("\t電話號碼:%s\n",temp->information.phone);
printf("=============================\n");
live=1;
}
x++;
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("請確定您所需要修改的學生資訊!");
getch();
change_pmenu_search();
return x;
}
}
int change_psearch_age()
{
STUDENT *temp;
temp=head;
int age,x=0,live=0;
printf("請輸入學生年齡:");
scanf("%d",&age);
while(temp!=NULL)
{
if(age==temp->information.age)
{
printf("姓名:%s\n",temp->information.mname);
printf("學號:%s\n",temp->information.schoolnum);
printf("性別:%s\n",temp->information.sex);
printf("年齡:%d\n",temp->information.age);
printf("家庭住址:%s\n",temp->information.address);
printf("電話號碼:%s\n",temp->information.phone);
printf("===========================\n");
live=1;
x++;
}
temp=temp->next;
}
if(live==0)
{
printf("未能找到符合條件的結果!!");
return -1;
}
else
{
printf("請確定您所需要修改的學生資訊!");
getch();
change_pmenu_search();
return x;
}
}
/****************************排序函式, head*******************/
//基本思路:選擇要進行排序的元素(年齡or學號) 選擇排序方法 :氣泡排序!
//注意使用連結串列排序,交換問題!
//進行輸出,呼叫輸出函式!
int psort_menu()
{
int chioce;
do
{
printf("\n");
printf("\t\t********************************\n");
printf("\t\t* 1.按學號排序 *\n");
printf("\t\t* 2.按年齡年齡 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
psort_schoolnum();
break;
case 2:
psort_age();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
void psort_schoolnum()//利用氣泡排序-----下節李珍同學講
{
STUDENT *p1,*p2,*ptemp,*pfinished=NULL;
for(p1=head;p1->next!=pfinished;)
{
for(p2=p1;p2->next!=pfinished;)
{
if(atof(p2->information.schoolnum)>atof(p2->next->information.schoolnum))
{
if(p2==p1)
{
p1=p2->next;
p2->next=p1->next;
p1->next=p2;
ptemp=p1;
}
else
{
ptemp->next=p2->next;
ptemp=p2->next;
p2->next=ptemp->next;
ptemp->next=p2;
}
}
else
{
ptemp=p2;
p2=p2->next;
}
}
pfinished=p2;
}
head=p1;
pdisplay_sort();
}
void psort_age()
{
STUDENT *p1,*p2,*ptemp,*pfinished=NULL;
for(p1=head;p1->next!=pfinished;)
{
for(p2=p1;p2->next!=pfinished;)
{
if(p2->information.age>p2->next->information.age)
{
if(p2==p1)
{
p1=p2->next;
p2->next=p1->next;
p1->next=p2;
ptemp=p1;
}
else
{
ptemp->next=p2->next;
ptemp=p2->next;
p2->next=ptemp->next;
ptemp->next=p2;
}
}
else
{
ptemp=p2;
p2=p2->next;
}
}
pfinished=p2;
}
head=p1;
pdisplay_sort();
}
//儲存連結串列,把連結串列儲存到相應檔案中
void save()
{
STUDENT *temp;
char ch;
temp=head;
char filename[LEN];
getch();
printf("是否把資訊儲存到檔案中?(是-Y 否-N):");
scanf("\n%c",&ch);
if(toupper(ch)=='Y')
{
printf("是否儲存到原檔案中?(是-Y 否-N):");
scanf("\n%c",&ch);
/*******************建立新檔案,並把連結串列寫入*************************/
if(toupper(ch)=='N')
{
printf("\n請輸入要儲存的檔案的完整路徑及檔名:");
scanf("\n");
gets(filename);
fp=fopen(filename,"wt");
while(temp!=NULL)
{
fwrite(temp,sizeof(Node),1,fp);
temp=temp->next;
}
fclose(fp);
}
else /****************把資料寫入原檔案fileopenname*********************/
{
fp=fopen("student_system.txt","wt");
while(temp!=NULL)
{
fwrite(temp,sizeof(Node),1,fp);
temp=temp->next;
}
fclose(fp);
}
}
}
admin.cpp
#include"head.h"
void admin()
{
if(judge_admin())
{
read_file();
menu_admin();
}
else
return ;
}
bool judge_admin()
{
int i=0,j=0;
FILE *pf;
char password[100];
char password1[100];
pf=fopen("order_admin.txt","rt");
fscanf(pf,"%s",password);
fclose(pf);
printf("\n請輸入密碼:");
do
{
password1[i]=getch();
if(password1[i]==0x1B)
{
return false;
}
if(password1[i]==13)
{
password1[i]='\0';
break;
}
i++;
printf("*");
}while(1);
if(!strcmp(MD5(password1),password))
return true;
else
{
printf("\n密碼錯誤!");
return false;
}
}
int menu_admin()
{
int chioce;
do
{
printf("\n\t\t*******************************\n");
printf("\t\t* 1.資訊錄入 *\n");
printf("\t\t* 2.資訊檢視 *\n");
printf("\t\t* 3.資訊修改 *\n");
printf("\t\t* 4.資訊查詢 *\n");
printf("\t\t* 5.資訊刪除 *\n");
printf("\t\t* 6.資訊排序 *\n");
printf("\t\t* 7.學生密碼管理 *\n");
printf("\t\t* 8.老師密碼管理 *\n");
printf("\t\t* 9.更改管理員密碼 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*******************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
pinput();
break;
case 2:
pdisplay();
break;
case 3:
change_pmenu_search();
break;
case 4:
pmenu_search();
break;
case 5:
delete_pmenu_search();
break;
case 6:
psort_menu();
break;
case 7:
read_file_order_stu();
menu_change_order_stu();
break;
case 8:
read_file_order_tea();
menu_change_order_tea();
break;
case 9:
change_order_admin();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
void change_order_admin()
{
int i=0;
FILE *fp;
FILE *fp1;
char password[100];
char oldpassword[100];
char newpassword[100];
char newpassword1[100];
fp=fopen("order_admin.txt","rt");
fscanf(fp,"%s",password);
fclose(fp);
printf("請輸入原來密碼:");
scanf("%s",oldpassword);
if(strcmp(password,MD5(oldpassword)))
{
printf("\n密碼錯誤!");
return ;
}
printf("\n請輸入新密碼:");
scanf("%s",newpassword);
strcpy(newpassword1,MD5(newpassword));
fp1=fopen("order_admin.txt","wt");
fprintf(fp1,"%s",newpassword1);
fclose(fp1);
printf("\n密碼修改完畢!");
}
/**************************admin_tea***************************/
int menu_change_order_tea()
{
int chioce;
do
{
printf("\n\t\t********************************\n");
printf("\t\t* 1.新增資訊 *\n");
printf("\t\t* 2.更改資訊 *\n");
printf("\t\t* 3.刪除資訊 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 0:
save_order_tea();
break;
case 1:
change_add_order_tea();
break;
case 2:
change_change_order_tea();
break;
case 3:
change_delete_order_tea();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
void change_delete_order_tea()//管理老師密碼
{
int x;
ORDER_TEA *temp=head_order_tea;
char username1[20];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
temp->last->next=temp->next;
printf("\n刪除完畢!");
return ;
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return ;
}
void change_change_order_tea()
{
int x,i=0;
ORDER_TEA *temp=head_order_tea;
char username1[100];
char password1[100];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
printf("\n請重新輸入密碼:");
scanf("%s",password1);
/*do
{
if(password1[i]=='\0') break;
password1[i]=password1[i]+i;
i++;
}while(1);*/
strcpy(temp->information.password,MD5(password1));
printf("修改完畢!");
return ;
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return ;
}
ORDER_TEA *change_add_order_tea()
{
int i=0;
char username2[100];
char password2[100];
char ch;
if(num_order_tea==0)//判斷是否是第一次錄入
{
iend_order_tea=inew_order_tea=(ORDER_TEA *)malloc(sizeof(ORDER_TEA));//申請空間
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_tea->information.username,username2);
printf("\n請輸入密碼:");
scanf("%s",password2);
/*do
{
if(password2[i]=='\0') break;
password2[i]=password2[i]+i;
i++;
}while(1);*/
strcpy(inew_order_tea->information.password,MD5(password2));
//錄入資訊
while(1)
{
num_order_tea++;
if(num_order_tea==1) //錄入第一個學生資訊時,第一個節點的指標指向
{
inew_order_tea->next=NULL;
inew_order_tea->last=NULL;
iend_order_tea =inew_order_tea;
head_order_tea =inew_order_tea;
}
else //在第一個節點的存在下,進行其他節點的錄入
{
inew_order_tea->next=NULL; //新建立節點next指向NULL
inew_order_tea->last=iend_order_tea; //新建立節點last指向上一個節點
iend_order_tea->next=inew_order_tea; //第一個next->下一個節點
iend_order_tea =inew_order_tea; //讓iend指向最後一個節點
}
inew_order_tea=(ORDER_TEA *)malloc(sizeof(ORDER_TEA));
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n') break;//判斷是否跳出迴圈
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_tea->information.username,username2);
printf("\n請輸入密碼:");
scanf("%s",password2);
/*do
{
if(password2[i]=='\0') break;
password2[i]=password2[i]+i;
i++;
}while(1);*/
strcpy(inew_order_tea->information.password,MD5(password2));
}
free(inew_order_tea); //釋放未儲存資料的節點
return head_order_tea;
}
else//非第一次錄入時
{
while(1)//進行迴圈輸入,並進行判斷,是否跳出迴圈
{
inew_order_tea=(ORDER_TEA *)malloc(sizeof(ORDER_TEA));
getch();
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_tea->information.username,username2);
printf("\n請輸入密碼:");
scanf("%s",password2);
do
{
if(password2[i]=='\0') break;
password2[i]=password2[i]+i;
i++;
}while(1);
strcpy(inew_order_tea->information.password,password2);
num_order_tea++;
inew_order_tea->next=NULL; //新建立節點next指向NULL
inew_order_tea->last=iend_order_tea; //新建立節點last指向上一個節點
iend_order_tea->next=inew_order_tea; //第一個next->下一個節點
iend_order_tea =inew_order_tea; //讓iend指向最後一個節點
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n')
break;
}
return head_order_tea;
}
}
void save_order_tea()
{
int i=0;
ORDER_TEA *temp=head_order_tea;
fp_order_tea=fopen("order_tea.txt","wt");
while(temp!=NULL)
{
fwrite(temp,sizeof(Node_order_tea),1,fp_order_tea);
temp=temp->next;
}
fclose(fp_order_tea);
}
/*************************admin_student***********************************/
int menu_change_order_stu()
{
int chioce;
do
{
printf("\n\t\t********************************\n");
printf("\t\t* 1.新增資訊 *\n");
printf("\t\t* 2.更改資訊 *\n");
printf("\t\t* 3.刪除資訊 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*********************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 0:
save_order_stu();
break;
case 1:
change_add_order_stu();
break;
case 2:
change_change_order_stu();
break;
case 3:
change_delete_order_stu();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
void change_delete_order_stu()//管理學生密碼
{
int x;
ORDER_STU *temp=head_order_stu;
char username1[20];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
temp->last->next=temp->next;
printf("\n刪除完畢!");
return ;
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return ;
}
void change_change_order_stu()
{
int x,i=0;
ORDER_STU *temp=head_order_stu;
char username1[100];
char password1[100];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
printf("\n請重新輸入密碼:");
scanf("%s",password1);
/*do
{
if(password1[i]=='\0') break;
password1[i]=password1[i]+i;
i++;
}while(1);*/
strcpy(temp->information.password,MD5(password1));
printf("修改完畢!");
return ;
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return ;
}
ORDER_STU *change_add_order_stu()
{
int i=0;
char username2[100];
char password2[100];
char ch;
if(num_order_stu==0)//判斷是否是第一次錄入
{
iend_order_stu=inew_order_stu=(ORDER_STU *)malloc(sizeof(ORDER_STU));//申請空間
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_stu->information.username,username2);
printf("\n請輸入密碼:");
scanf("%s",password2);
strcpy(inew_order_stu->information.password,MD5(password2));
//錄入資訊
while(1)
{
num_order_stu++;
if(num_order_stu==1) //錄入第一個學生資訊時,第一個節點的指標指向
{
inew_order_stu->next=NULL;
inew_order_stu->last=NULL;
iend_order_stu =inew_order_stu;
head_order_stu =inew_order_stu;
}
else //在第一個節點的存在下,進行其他節點的錄入
{
inew_order_stu->next=NULL; //新建立節點next指向NULL
inew_order_stu->last=iend_order_stu; //新建立節點last指向上一個節點
iend_order_stu->next=inew_order_stu; //第一個next->下一個節點
iend_order_stu =inew_order_stu; //讓iend指向最後一個節點
}
inew_order_stu=(ORDER_STU *)malloc(sizeof(ORDER_STU));
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n') break;//判斷是否跳出迴圈
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_stu->information.username,MD5(password2));
printf("\n請輸入密碼:");
scanf("%s",password2);
do
{
if(password2[i]=='\0') break;
password2[i]=password2[i]+i;
i++;
}while(1);
strcpy(inew_order_stu->information.password,password2);
}
free(inew_order_stu); //釋放未儲存資料的節點
return head_order_stu;
}
else//非第一次錄入時
{
while(1)//進行迴圈輸入,並進行判斷,是否跳出迴圈
{
inew_order_stu=(ORDER_STU *)malloc(sizeof(ORDER_STU));
getch();
printf("\n請輸入使用者名稱:");
scanf("%s",username2);
strcpy(inew_order_stu->information.username,username2);
printf("\n請輸入密碼:");
scanf("%s",password2);
do
{
if(password2[i]=='\0') break;
password2[i]=password2[i]+i;
i++;
}while(1);
strcpy(inew_order_stu->information.password,password2);
num_order_stu++;
inew_order_stu->next=NULL; //新建立節點next指向NULL
inew_order_stu->last=iend_order_stu; //新建立節點last指向上一個節點
iend_order_stu->next=inew_order_stu; //第一個next->下一個節點
iend_order_stu =inew_order_stu; //讓iend指向最後一個節點
printf("資訊輸入完畢,是否繼續?(是-Y 否-N):");
scanf("\n%c",&ch);
if(ch=='N'||ch=='n')
break;
}
return head_order_stu;
}
}
void save_order_stu()
{
int i=0;
ORDER_STU *temp=head_order_stu;
fp_order_stu=fopen("order_stu.txt","wt");
while(temp!=NULL)
{
fwrite(temp,sizeof(Node_order_stu),1,fp_order_stu);
temp=temp->next;
}
fclose(fp_order_stu);
}
/***************************************************************************/
student.cpp
#include"head.h"
/*****************************student**********************************/
void student()
{
read_file_order_stu();
if(judge_stu())
{
read_file();
menu_stu();
}
else return ;
}
int menu_stu()
{
int chioce;
do
{
printf("\n\t\t*******************************\n");
printf("\t\t* 1.資訊檢視 *\n");
printf("\t\t* 2.資訊查詢 *\n");
printf("\t\t* 3.資訊排序 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*******************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
pdisplay();
break;
case 2:
pmenu_search();
break;
case 3:
psort_menu();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
bool judge_stu()
{
int x,i=0,j=0;
ORDER_STU *temp=head_order_stu;
char username1[100];
char password1[100];
char password2[100];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
printf("\n請輸入密碼:");
do
{
password1[i]=getch();
if(password1[i]==13)
{
password1[i]='\0';
break;
}
i++;
printf("*");
}while(1);
/*do{
if(temp->information.password[j]=='\0')
{
password2[j]='\0';
break;
}
password2[j]=temp->information.password[j]-j;
j++;
}while(1);*/
strcpy(password2,temp->information.password);
if(!strcmp(MD5(password1),password2))
return true;
else
{
printf("\n密碼錯誤!");
return false;
}
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return false;
}
int read_file_order_stu()
{
int i;
int fno,fsize;
if((fp_order_stu=fopen("order_stu.txt","rt"))==NULL)
{
printf("\n庫檔案不存在!\n");
return 0;
}
rewind(fp_order_stu); //使檔案內部指標移動到檔案的開始位置
fno=fileno(fp_order_stu); //獲取檔案描述字
fsize=filelength(fno); //計算檔案大小,以位元組為單位
num_order_stu=fsize/sizeof(Node_order_stu); //計算檔案包含的學生資訊數目
iend_order_stu=inew_order_stu=(ORDER_STU *)malloc(sizeof(ORDER_STU));//申請動態空間
fread(inew_order_stu,sizeof(Node_order_stu),1,fp_order_stu); //以Node(結構體)的空間大小讀資料
for(i=1;i<=num_order_stu;i++) //利用for迴圈建立連結串列,並把資料儲存到其中
{
if(i==1) //第一個節點的建立
{
inew_order_stu->next=head_order_stu;
inew_order_stu->last=NULL; //雙向連結串列
iend_order_stu=inew_order_stu;
head_order_stu=inew_order_stu;
}
else
{
inew_order_stu->next=NULL;
inew_order_stu->last=iend_order_stu;
iend_order_stu->next=inew_order_stu;
iend_order_stu =inew_order_stu;
}
inew_order_stu=(ORDER_STU *)malloc(sizeof(ORDER_STU));
fread(inew_order_stu,sizeof(Node_order_stu),1,fp_order_stu);
}
free(inew_order_stu);//釋放最後一個沒有儲存資料的節點
fclose(fp_order_stu);//關閉檔案
return num_order_stu;
}
/****************************************************/
teacher.cpp
#include"head.h"
/************************teacher************************************/
void teacher()
{
read_file_order_tea();
if(judge_tea())
{
read_file();
menu_tea();
}
else return ;
}
int menu_tea()
{
int chioce;
do
{
printf("\n\t\t*******************************\n");
printf("\t\t* 1.資訊錄入 *\n");
printf("\t\t* 2.資訊檢視 *\n");
printf("\t\t* 3.資訊修改 *\n");
printf("\t\t* 4.資訊查詢 *\n");
printf("\t\t* 5.資訊刪除 *\n");
printf("\t\t* 6.資訊排序 *\n");
printf("\t\t* 0.退出 *\n");
printf("\t\t*******************************\n");
printf("\t\t請選擇:");
scanf("%d",&chioce);
switch(chioce)
{
case 1:
pinput();
break;
case 2:
pdisplay();
break;
case 3:
change_pmenu_search();
break;
case 4:
pmenu_search();
break;
case 5:
delete_pmenu_search();
break;
case 6:
psort_menu();
break;
default:
break;
}
}while(chioce!=0);
return 0;
}
bool judge_tea()
{
int x,i=0,j=0;
ORDER_TEA *temp=head_order_tea;
char username1[100];
char password1[100];
char password2[100];
printf("\n請輸入使用者名稱:");
scanf("%s",username1);
while(temp!=NULL)
{
if(!strcmp(temp->information.username,username1))
{
printf("\n請輸入密碼:");
do
{
password1[i]=getch();
if(password1[i]==13)
{
password1[i]='\0';
break;
}
i++;
printf("*");
}while(1);
/*do{
if(temp->information.password[j]=='\0')
{
password2[j]='\0';
break;
}
password2[j]=(temp->information.password[j])-j;
j++;
}while(1);*/
strcpy(password2,temp->information.password);
if(!strcmp(MD5(password1),password2))
return true;
else
{
printf("\n密碼錯誤!");
return false;
}
}
temp=temp->next;
x++;
}
printf("不存在此使用者名稱!");
return false;
}
int read_file_order_tea()
{
int i;
int fno,fsize;
if((fp_order_tea=fopen("order_tea.txt","rt"))==NULL)
{
printf("\n庫檔案不存在!\n");
return 0;
}
rewind(fp_order_tea); //使檔案內部指標移動到檔案的開始位置
fno=fileno(fp_order_tea); //獲取檔案描述字
fsize=filelength(fno); //計算檔案大小,以位元組為單位
num_order_tea=fsize/sizeof(Node_order_tea); //計算檔案包含的學生資訊數目
iend_order_tea=inew_order_tea=(ORDER_TEA *)malloc(sizeof(ORDER_TEA));//申請動態空間
fread(inew_order_tea,sizeof(Node_order_tea),1,fp_order_tea); //以Node(結構體)的空間大小讀資料
for(i=1;i<=num_order_tea;i++) //利用for迴圈建立連結串列,並把資料儲存到其中
{
if(i==1) //第一個節點的建立
{
inew_order_tea->next=head_order_tea;
inew_order_tea->last=NULL; //雙向連結串列
iend_order_tea=inew_order_tea;
head_order_tea=inew_order_tea;
}
else
{
inew_order_tea->next=NULL;
inew_order_tea->last=iend_order_tea;
iend_order_tea->next=inew_order_tea;
iend_order_tea =inew_order_tea;
}
inew_order_tea=(ORDER_TEA *)malloc(sizeof(ORDER_TEA));
fread(inew_order_tea,sizeof(Node_order_tea),1,fp_order_tea);
}
free(inew_order_tea);//釋放最後一個沒有儲存資料的節點
fclose(fp_order_tea);//關閉檔案
return num_order_tea;
}
MD5.cpp
/*************************************************************************
> File Name: md5_1.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月22日 星期三 16時12分30秒
************************************************************************/
#include"head.h"
//第一位1 其後若干個0,用於MD5Final函式時的補足
/************************
* 函式功能:初始化一個MD5 text
* 函式引數:MD5 text 指標
* ***********************/
//初始化
void MD5Init(MD5_CTX *context)
{
context->count[0] = 0;
context->count[1] = 0;
//分別賦固定值
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
}
/************************************************
* 函式功能:對一個MD5 text,把輸入的資料進行分組,並進行加密
* 未用到的資料把其儲存在MD5 text中。
*
* 引數分析:
* MD5_CTX *context :一個MD5 text
* unsigned char *input :新新增的資料
* unsigned int inputlen :新新增資料的長度(位元組)
*
***********************************************/
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
{
unsigned int i = 0,index = 0,partlen = 0;
//index:當前狀態的位數對64取餘,其單位是位元組
//也可以寫作: index=(context->count[0]/8)%64
index = (context->count[0] >> 3) & 0x3F;
//partlen:可以補齊64位元組的位元組數
partlen = 64 - index;
//下面程式碼是解決一個unsignde int 無法儲存極大資料導致溢位的問題
//當前位數加上新新增的位數,由於inputlen是以位元組為單位,所以其轉換為位數
//相當於context->count[0] += inputlen*8;
context->count[0] += inputlen << 3;
//當其出現溢位的情況時,通過以下操作把兩個16位的數連在一塊,生成一個
//32位的二進位制數串,從而擴大其儲存範圍
if(context->count[0] < (inputlen << 3))
context->count[1]++;
//該語句可替換為 context->count[1]+=(inputlen<<3)>>32;
//便於理解
context->count[1] += inputlen >> 29;
//當其輸入位元組數的大於其可以補足64位元組的位元組數,進行補足
if(inputlen >= partlen)
{
//向buffer中補足partlen個位元組,使其到達64位元組
memcpy(&context->buffer[index],input,partlen);
//buffer達到64位元組512位,則把其作為一組進行運算
MD5Transform(context->state,context->buffer);
//如果輸入的資料還可以組成多個64位元組,則把其可以組成
//的作為若干組進行運算
for(i = partlen;i+64 <= inputlen;i+=64)
MD5Transform(context->state,&input[i]);
//恢復0值,照應 下面 把輸入 剩餘位元組(不能組成64位元組組) 儲存的操作
index = 0;
}
//否則,把輸入的資料按順序放在原來資料後面
else
{
i = 0;
}
//放置剩餘資料
memcpy(&context->buffer[index],&input[i],inputlen-i);
}
/*************************************************
* 函式功能:對資料進行補足,並加入資料位數資訊,並進一步加密
*
* 引數分析:
* MD5_CTX *context :一個MD5 text
* unsigned char digest[16] :儲存加密結果的陣列
*************************************************/
void MD5Final(MD5_CTX *context,unsigned char digest[16])
{
unsigned int index = 0,padlen = 0;
//bits: 8個位元組,64位
unsigned char bits[8];
//index:對64取餘結果
index = (context->count[0] >> 3) & 0x3F;
//因為要填充滿足使其位長對512求餘的結果等於448(56位)
//所以當其所剩餘的數小於56位元組,則填充56-index位元組,
//否則填充120-index位元組
//這裡padlen代表其所需填充的位元組
padlen = (index < 56)?(56-index):(120-index);
//然後,在這個結果後面附加一個以64位二進位制表示的填充前資料長度。
//把填充前資料資料長度轉換後放到bit字元陣列中
MD5Encode(bits,context->count,8);
//根據已經儲存好的陣列PADDING,在資訊的後面填充一個1和無數個0,
//直到滿足上面的條件時才停止用0對資訊的填充
//其填充後進行了一系列的加密操作,其定剩餘48個位元組
MD5Update(context,PADDING,padlen);
//在最後新增進8個位元組的資料長度資訊,最後湊成一組,進行一次加密處理
MD5Update(context,bits,8);
//把最終得到的加密資訊變成字元輸出,共16位元組
MD5Encode(digest,context->state,16);
}
/**********************************************************
* 函式功能:利用位操作,按1->4方式把數字分解成字元
*
* 引數分析:
* unsigned char *output :輸出的字元的陣列
* unsigned int *input :輸入數字的陣列
* unsigned int len : 輸入數字陣列的長度(單位:位)
* *********************************************************/
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
//這裡& 0xFF為取後8位
//i代表數字陣列下標
//j代表字元陣列下標
//把數字的8、8-16、16-24、24-32分別賦值給字元
output[j] = input[i] & 0xFF;
output[j+1] = (input[i] >> 8) & 0xFF;
output[j+2] = (input[i] >> 16) & 0xFF;
output[j+3] = (input[i] >> 24) & 0xFF;
i++;
j+=4;
}
}
/**********************************************************
* 函式功能:利用位操作,按4->1方式把字元合成數字
*
* 引數分析:
* unsigned int *output :輸出的數字的陣列
* unsigned char *input :輸入字元的陣列
* unsigned int len : 輸入字元的長度 (單位:位)
* *********************************************************/
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
//利用位操作,把四個單位為1位元組的字元,合成一個單位為4位元組的數字
//因為FF GG HH II和非線性函式都只能對數字進行處理
//第一個字元佔前8位,第二個佔8-16位,第三個佔16-24位,第四個佔
//24-32位。
//i代表數字陣列下標
//j代表字元陣列下標
output[i] = (input[j]) |
(input[j+1] << 8) |
(input[j+2] << 16) |
(input[j+3] << 24);
i++;
j+=4;
}
}
/**************************************************************
* 函式功能:對512位的block資料進行加密,並把加密結果存入state陣列中
* 對512位資訊(即block字元陣列)進行一次處理,每次處理包括四輪
*state[4]:md5結構中的state[4],用於儲存對512bits資訊加密的中間結果或者最終結果
* block[64]:欲加密的512bits資訊或其中間資料
***************************************************************/
void MD5Transform(unsigned int state[4],unsigned char block[64])
{
//a b c d繼承上一個加密的結果,所以其具有繼承性
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
//這裡只需用到16個,我把原來的unsiged int x[64] 改為了 x[16]
unsigned int x[16];
//把字元轉化成數字,便於運算
MD5Decode(x,block,64);
//具體函式方式固定,不再贅述
/*************第一輪******************/
FF(a, b, c, d, x[ 0], 7, 0xd76aa478);
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);
FF(c, d, a, b, x[ 2], 17, 0x242070db);
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);
FF(d, a, b, c, x[ 5], 12, 0x4787c62a);
FF(c, d, a, b, x[ 6], 17, 0xa8304613);
FF(b, c, d, a, x[ 7], 22, 0xfd469501);
FF(a, b, c, d, x[ 8], 7, 0x698098d8);
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);
FF(c, d, a, b, x[10], 17, 0xffff5bb1);
FF(b, c, d, a, x[11], 22, 0x895cd7be);
FF(a, b, c, d, x[12], 7, 0x6b901122);
FF(d, a, b, c, x[13], 12, 0xfd987193);
FF(c, d, a, b, x[14], 17, 0xa679438e);
FF(b, c, d, a, x[15], 22, 0x49b40821);
/*************第二輪*****************/
GG(a, b, c, d, x[ 1], 5, 0xf61e2562);
GG(d, a, b, c, x[ 6], 9, 0xc040b340);
GG(c, d, a, b, x[11], 14, 0x265e5a51);
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
GG(a, b, c, d, x[ 5], 5, 0xd62f105d);
GG(d, a, b, c, x[10], 9, 0x2441453);
GG(c, d, a, b, x[15], 14, 0xd8a1e681);
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);
GG(d, a, b, c, x[14], 9, 0xc33707d6);
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);
GG(b, c, d, a, x[ 8], 20, 0x455a14ed);
GG(a, b, c, d, x[13], 5, 0xa9e3e905);
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);
GG(c, d, a, b, x[ 7], 14, 0x676f02d9);
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
/*************第三輪*****************/
HH(a, b, c, d, x[ 5], 4, 0xfffa3942);
HH(d, a, b, c, x[ 8], 11, 0x8771f681);
HH(c, d, a, b, x[11], 16, 0x6d9d6122);
HH(b, c, d, a, x[14], 23, 0xfde5380c);
HH(a, b, c, d, x[ 1], 4, 0xa4beea44);
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
HH(b, c, d, a, x[10], 23, 0xbebfbc70);
HH(a, b, c, d, x[13], 4, 0x289b7ec6);
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);
HH(b, c, d, a, x[ 6], 23, 0x4881d05);
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);
HH(d, a, b, c, x[12], 11, 0xe6db99e5);
HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);
/*************第四輪******************/
II(a, b, c, d, x[ 0], 6, 0xf4292244);
II(d, a, b, c, x[ 7], 10, 0x432aff97);
II(c, d, a, b, x[14], 15, 0xab9423a7);
II(b, c, d, a, x[ 5], 21, 0xfc93a039);
II(a, b, c, d, x[12], 6, 0x655b59c3);
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
II(c, d, a, b, x[10], 15, 0xffeff47d);
II(b, c, d, a, x[ 1], 21, 0x85845dd1);
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);
II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
II(c, d, a, b, x[ 6], 15, 0xa3014314);
II(b, c, d, a, x[13], 21, 0x4e0811a1);
II(a, b, c, d, x[ 4], 6, 0xf7537e82);
II(d, a, b, c, x[11], 10, 0xbd3af235);
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
II(b, c, d, a, x[ 9], 21, 0xeb86d391);
//更換原來的結果
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
char * MD5(char *encrypt)
{
MD5_CTX md5; //定義一個MD5 text
MD5Init(&md5);//初始化
unsigned char decrypt[16]; //加密結果
MD5Update(&md5,(unsigned char*)encrypt,strlen(encrypt));//進行初步分組加密
MD5Final(&md5,decrypt); //進行後序的補足,並加密
return (char *)decrypt;
}
head.h
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#include<io.h>
#define LEN 100
#define PAGE 3 //分頁輸出時,每頁的學生個數
void admin();
int menu_admin();
void change_change_order_tea();
int menu_change_order_tea();
void change_delete_order_tea();
void teacher();
int menu_tea();
bool judge_tea();
int read_file_order_tea();
void change_change_order_stu();
int menu_change_order_stu();
void change_delete_order_stu();
void student();
int menu_stu();
bool judge_stu();
int read_file_order_stu();
bool judge_admin();
void change_order_admin();
int menu();
int pmenu_search();
int read_file();
void pdisplay();
void pdisplay_sort();
int psearch_mname();
int psearch_schoolnum();
int psearch_phone();
int psearch_sex();
int psearch_age();
int delete_pmenu_search();
int delete_psearch_schoolnum();
int delete_psearch_mname();
int delete_psearch_phone();
int delete_psearch_age();
int delete_psearch_sex();
int change_pmenu_search();
int change_psearch_schoolnum();
int change_psearch_mname();
int change_psearch_phone();
int change_psearch_age();
int change_psearch_sex();
int psort_menu();
void psort_age();
void psort_schoolnum();
void save_order_tea();
void save();
void save_order_stu();
typedef struct {
char mname[9];
char schoolnum[15];
char sex[3];
int age;
char address[20];
char phone[15];
}Node;
typedef struct student
{
Node information;
struct student *next;
struct student *last;
}STUDENT;
/*******************md5*********************/
/***********************************
* 非線性函式
* (&是與,|是或,~是非,^是異或)
*
* 這些函式是這樣設計的:
* 如果X、Y和Z的對應位是獨立和均勻的,
* 那麼結果的每一位也應是獨立和均勻的。
*
* 函式F是按逐位方式操作:如果X,那麼Y,否則Z。
* 函式H是逐位奇偶操作符
**********************************/
#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (y & ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
/**************************************
*向右環移n個單位
* ************************************/
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
/****************************************************
* 每次操作對a,b,c和d中的其中三個作一次非線性函式運算
* F(b,c,d) G(b,c,d) H(b,c,d) I(b,c,d)
*
* 然後將所得結果加上 第四個變數(a),
* F(b,c,d)+a
*
* 文字的一個子分組(x)
* F(b,c,d)+a+x
*
* 和一個常數(ac)。
* F(b,c,d)+a+x+ac
*
* 再將所得結果向右環移一個不定的數(s),
* ROTATE_LEFT( F(b,c,d)+a+x+ac , s )
*
* 並加上a,b,c或d中之一(b)。
* ROTATE_LEFT( F(b,c,d)+a+x+ac , s )+b
*
* 最後用該結果取代a,b,c或d中之一(a)。
* a=ROTATE_LEFT( F(b,c,d)+a+x+ac , s )+b
*
* ***************************************************/
#define FF(a,b,c,d,x,s,ac) { a += F(b,c,d) + x + ac; a = ROTATE_LEFT(a,s); a += b; }
#define GG(a,b,c,d,x,s,ac) { a += G(b,c,d) + x + ac; a = ROTATE_LEFT(a,s); a += b; }
#define HH(a,b,c,d,x,s,ac) { a += H(b,c,d) + x + ac; a = ROTATE_LEFT(a,s); a += b; }
#define II(a,b,c,d,x,s,ac) { a += I(b,c,d) + x + ac; a = ROTATE_LEFT(a,s); a += b; }
//儲存一個MD5 text資訊
typedef struct
{
unsigned int count[2];
//記錄當前狀態,其資料位數
unsigned int state[4];
//4個數,一共32位 記錄用於儲存對512bits資訊加密的中間結果或者最終結果
unsigned char buffer[64];
//一共64位元組,512位
}MD5_CTX;
//函式宣告區,每個函式在下面都有較詳細說明,這裡不再贅述
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
void MD5Transform(unsigned int state[4],unsigned char block[64]);
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
char * MD5(char *encrypt);
typedef struct
{
char username[100];
char password[100];
}Node_order_tea;
typedef struct order_tea
{
Node_order_tea information;
struct order_tea *next;
struct order_tea *last;
}ORDER_TEA;
typedef struct
{
char username[100];
char password[100];
}Node_order_stu;
typedef struct order_stu
{
Node_order_stu information;
struct order_stu *next;
struct order_stu *last;
}ORDER_STU;
//全域性變數宣告
extern int num; //檔案中總的學生資訊個數
extern STUDENT *head,*iend,*inew;
extern FILE *fp; //檔案指標
extern int num_order_tea; //檔案中總的學生資訊個數
extern ORDER_TEA *head_order_tea,*iend_order_tea,*inew_order_tea;
extern FILE *fp_order_tea;
extern int num_order_stu; //檔案中總的學生資訊個數
extern ORDER_STU *head_order_stu,*iend_order_stu,*inew_order_stu;
extern FILE *fp_order_stu;
extern unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void inputone(STUDENT *temp);
STUDENT *pinput();
int change_one(STUDENT *pTemp);
void displayone(STUDENT *temp);
ORDER_TEA *change_add_order_tea();
ORDER_STU *change_add_order_stu();
注:登陸密碼為:1234567
具體檔案在我上傳的資源中,名字為資訊管理系統
相關文章
- 自寫資訊管理系統—— C 實現
- 學生資訊管理系統(c語言實訓)C語言
- 就業資訊管理系統設計與實現就業
- 通訊錄管理系統(C++實現)C++
- C++圖書館管理系統 [STL實現]C++
- C++實現管理系統的示例程式碼C++
- 教你如何運用python實現學生資訊管理系統Python
- python實現學生資訊管理系統(從淺到深)Python
- C++實現控制檯學生學籍管理系統C++
- lims實驗室管理系統是什麼?實驗室資訊管理系統介紹!
- 基於檔案管理的學生資訊管理系統(C語言/C++)C語言C++
- C++課程設計:學生資訊管理系統C++
- Python編寫簡單的學生資訊管理系統Python
- 用ssh思想寫的一個學生資訊管理系統
- HttpClient和HtmlParser配合實現自動登陸系統抽取頁面資訊HTTPclientHTML
- CRM系統實現資訊共享如何操作
- 財務管理系統如何幫助企業實現財務自動化管理?
- 多系統管理混亂?SAP系統整合其他系統實現統一管理
- Binder系統_c++程式實現C++
- 醫學實驗室資訊管理系統原始碼原始碼
- 實驗室資訊管理系統(LIMS)知識大全
- 寫作業系統之實現程式作業系統
- WEB資訊管理系統、資料展現分析系統 快速搭建平臺Web
- 作業系統——c++實現頁式虛擬儲存管理作業系統C++
- C語言-超市倉庫管理系統的設計與實現C語言
- 資訊系統監理之資訊系統專案管理專案管理
- Thymeleaf+SpringBoot+SpringDataJPA實現的中小醫院資訊管理系統Spring Boot
- 如何自主搭建資訊管理系統
- 車間管理資訊系統
- 4-資訊系統管理
- 高校學生資訊管理系統C#窗體版更新(一)C#
- 實驗室資訊管理系統(LIMS)軟體大盤點
- 學生資訊管理系統解析之介面實踐篇
- 學生資訊管理系統(二)刪除資訊
- 資訊源管理系統是資訊部門自身資訊化
- 基於java的大學生健康資訊管理系統的設計與實現Java
- 工程管理系統之Spring Cloud+實現工程管理系統原始碼SpringCloud原始碼
- PXE實現系統自動化安裝