通過學習學生信息管理系統軟件,C程序中,如何設計和編寫一個應用系統


C語言將計算機的輸入輸出設備都看作是文件

那麼,如果寫一個字符串到一個文件中,是什麼方式呢?顯示到屏幕上是默認的輸出文件,如果是硬盤中的一個文件,首先要打開一個文件,然後才能往裏寫,那麼就要告訴程序這個文件在什麼地方,按照什麼樣的方式打開(讀、寫、讀和寫、添加、覆蓋等),然後打開後要給這個打開的文件一個符號(指針變量),表示後續的讀和寫都是針對這個文件的,而不是到屏幕的,這個指針變量以後就代表了文件自身了。


例如學生信息管理系統中,需要同時保存一個學生的姓名,性別,年齡等信息,那麼設置變量保存很多同學的這些信息就有點不太方便。類似一個登記本,每一頁只能寫名字,如果你要登記其他的信息,又要添加一個登記本,只能寫性別,如果登記年齡,又要添加一個登記本,只能寫年齡,….,多麼的不方便,還容易混亂。解決的方法你一定想,多麼簡單,一個登記本一頁中,同時寫姓名,性別,年齡不就行了嗎?C語言也是這樣,如果定義一種形式,一個變量同時記錄很多的信息,這樣在管理系統中,就方便很多了。這就是結構體。


結構體首先要定義,因爲每個程序用到的組合在一起的信息不一樣,例如學生信息管理系統中,可能要將學號、姓名、性別、年齡、班級組合到一起,所以 第一行用struct告訴程序,下面是一個結構體,後面的stu是這個結構體的類型,類似整數用int表示,這個stu是你自己起的名字。





#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<conio.h>

#include<malloc.h>

#include<time.h>

#define LEN sizeof(struct readerinf)

#define LON sizeof(struct bookinf)

FILE *pf,*pb;

struct borrow                /*定義被借圖書簡單信息*/

{

long int book;

    int outyear;             /*爲查看用戶信息時,可以查看書本超期時間所定*/

int outmonth;

int outday;

long int tim;            /*爲簡化超期罰款函數所定*/

};

struct bookinf                /*定義圖書結構體*/

{

char name[31];

char author[21];

char pubcompany[100];      /*出版社*/

char pubdate[20];         /*出版時間*/

int price;                /*價格*/

long int ISBN;                 /*圖書編號*/

char category[30];             /*分類*/

    int condition;            /*是否在架 1:在架 0:已借 2:再借*/

int borrowednum;          /*借閱次數*/

    struct bookinf *next;

};

struct readerinf              /*定義學生結構體*/

{

char name[30]; 

char sex[4]; 

char birthday[20];        /*出生年月*/

char college[20];           /*學院*/

char secretnum[10];         /*secretnum=(密碼-20)*2 */

long int ID;                /*學號*/

char type[20];              /*讀者類型*/

int balance;                /*賬戶餘額*/

int bornum;                 /*當前借閱數*/ 

int outdatenum;             /*超期圖書數*/

struct borrow b[30];        /*一個結構體變量,記錄圖書和超期時間*/

struct readerinf *next; /*指向下一位同學的指針*/

};

struct readerinf *head1,*p1,*p2;

struct bookinf *head2,*b1,*b2;




/*以下是對系統管理員模塊使用函數的聲明*/


int loadone();                                         /*登陸*/

void managementone();                                  /*進入管理員的各種操作*/

struct readerinf *creat();                             /*初始化鏈表函數*/ 

struct readerinf *addperson(struct readerinf *head);   /*添加用戶函數*/

struct readerinf *delperson(struct readerinf *head);   /*刪除用戶函數*/

void showperson(struct readerinf *head);               /*查看用戶信息*/

void delsecret(struct readerinf *head);                /*清空用戶密碼*/

void storagereader(struct readerinf *p);            /*將鏈表信息存至文件*/


/*以下是對圖書管理員模塊使用函數的聲明*/

int loadtwo();                                         /*登陸*/

void managementtwo();                                  /*進入管理員的各種操作*/

struct bookinf *addbook(struct bookinf *head);        /*添加圖書*/

struct bookinf *delbook(struct bookinf *head);        /*刪除圖書*/

void rewritebook(struct bookinf *b);                /*修改圖書信息*/

void recharge(struct readerinf *p);                 /*用戶充值*/


/*以下是對讀者模塊函數使用的聲明*/

struct readerinf *loadthree();                 /*登陸*/

void operation();                                      /*進入讀者的各種操作*/

struct bookinf *begin();                               /*初始化鏈表函數*/

void borrowbook(struct bookinf *b1,struct readerinf *p);                 /*借書*/

void renewbook(struct readerinf *p);                  /*續借*/  

void returnbook(struct readerinf *p);                 /*還書*/

void checkbook(struct bookinf *b);                  /*查找圖書*/

void rewritereader(struct readerinf *p3);            /*修改讀者信息*/

void storagebook(struct bookinf *b);                /*將鏈表信息存至文件*/


void statistic();                                    /*統計功能*/

void fine();                                          /*超期罰款函數*/


int fh1=4;/*返回上層功能所需,方便修改*/

int zh=1000;/*系統管理員的賬戶、mima=(密碼-20)*2*/

char a[5]={'<','@','D','H'},c;/*實際密碼爲2468*/

struct librarian/*圖書管理員的賬戶、加密後密碼=(密碼-20)*2*/

{

int z;

char m[20];

}liber[5]={{1001,"<<<<"},{1002,"@@@@"},{1003,"DDDD"},{1004,"HHHH"},{1005,"<@DH"}};


/*

函數功能:選擇用戶類型,進入對應登陸界面

*/

void main()

{   

int op;

fine();

printf(" +++++歡迎進入圖書管理系統+++++\n");

while(1)

{

printf(" *      系統管理員請按1         *\n");

printf(" *      圖書管理員按2           *\n");

printf(" *      讀者請按3               *\n");

printf(" *      查看最受歡迎的書請按4   *\n");

printf(" *      退出請按0               *\n");

printf(" *  請輸入0--4,其他指令不可用。*\n");

printf(" ++++++++++++++++++++++++++++++++\n");

scanf("%d",&op);

switch(op)

{

case 1: if(loadone()==1)

managementone();break;

case 2:if(loadtwo()==1)

  managementtwo();break;

case 3:if((p1=loadthree())!=NULL)

  operation();break; 

case 0:exit(0);break;

case 4:statistic();break;

default : printf("沒有對應的系統指令,請查證重輸\n");

}

}

}


/*以下是系統管理員模塊中的函數定義*/


/*

函數功能:系統管理員登陸

輸出參數:1--登陸成功,0--返回上層

函數流程:

1. 輸入用戶名,若返回上層輸入4

2. 若有這個用戶,則繼續輸入密碼。密碼正確則返回1,

3. 否則繼續輸入。

*/

int loadone()                                              

{

int i,n=0,z1;

char c;

printf("返回上層請按4\n");

printf("請輸入用戶名\n");

scanf("%d",&z1);

if(fh1==z1)

return(0);

while(zh!=z1)

{

printf("該用戶不存在\n");

scanf("%d",&z1);

};

printf("請輸入密碼\n");

while(n!=i)

{

n=0;

for(i=0;a[i]!='\0';i++)

{

c=getch();

if(a[i]==(c-20)*2)

n++;

}

if(n!=i)

printf("您輸入的密碼有誤\n");

}

return(1);

}


/*

函數功能:系統管理員選擇對應功能,進行操作

*/

void managementone()                                   

{

int choice=0;

head1=creat();

while(choice!=fh1)

{   

printf("+++++++++++++++++++++++++++++++++++++++++\n");

printf("添加用戶請按0\n");

printf("刪除用戶請按1\n");

printf("查看用戶信息請按2\n");

printf("清空用戶密碼請按3\n");

printf("返回上層請按4\n");

printf("請輸入0--4,其他指令不可用。\n");

scanf("%d",&choice);

switch (choice)

{

case 0:head1=addperson(head1);break; /*添加用戶*/

case 1:head1=delperson(head1);break; /*刪除用戶*/

case 2:showperson(head1);break;    /*查看用戶信息*/

case 3:delsecret(head1);break;     /*清空用戶密碼*/

case 4:choice=4;break;             /*返回*/

default: printf("沒有對應的系統指令,請查證重輸\n");break;

}

}

storagereader(head1);

}

/*

函數功能:讀取文件中的信息,存至鏈表中對應位置

輸出參數:head--鏈表頭指針

函數流程:

    1.打開文件

2.文件沒有結束則讀取文件信息並存至鏈表

3.文件結束則返回頭指針

*/

struct readerinf *creat(void)       /*初始化讀者信息鏈表函數*/

{

int i;

struct readerinf *head;

pf=fopen("reader.txt","r+");

if(pf==NULL)

{

printf("不能打開文件\n");

exit(0);

}

if(pf==-1)                /*若文件爲空文件*/

head=NULL;

else

{

p2=(struct readerinf*)malloc(LEN);

fscanf(pf,"%s %s %s %s %s %d %s %d %d %d",

p2->name,p2->sex,p2->birthday,p2->college,p2->secretnum,

&p2->ID,p2->type,&p2->balance,&p2->bornum,&p2->outdatenum);

for(i=0;i<(p2->bornum);i++)

{

fscanf(pf,"%d%d%d%d%d",&p2->b[i].book,&p2->b[i].outyear,

&p2->b[i].outmonth,&p2->b[i].outday,&p2->b[i].tim);

}

head=p2;

while(!feof(pf))

{

p1=(struct readerinf*)malloc(LEN);          /*申請一塊空間給P1*/

fscanf(pf,"%s %s %s %s %s %d %s %d %d %d",

p1->name,p1->sex,p1->birthday,p1->college,p1->secretnum,

&p1->ID,p1->type,&p1->balance,&p1->bornum,&p1->outdatenum);/*讀取信息*/

for(i=0;i<(p1->bornum);i++)

{

fscanf(pf,"%d%d%d%d%d",&p1->b[i].book,&p1->b[i].outyear,

&p1->b[i].outmonth,&p1->b[i].outday,&p1->b[i].tim);

}

p2->next=p1;

p2=p1;

}

p2->next=NULL;

fclose(pf);

}

return(head);

}

/*

函數功能:添加用戶

輸入/輸出參數:均爲鏈表指頭針head

函數流程:

    1.若鏈表爲空,申請一塊空間給頭指針

2.否則申請一塊空間給p

3.輸入用戶的信息,並對密碼加密

4.將p指向的節點連到鏈表上

*/

struct readerinf *addperson(struct readerinf *head)          

{

int j;

struct readerinf *p,*p3;

printf("請輸入要添加用戶的信息\n");

printf("姓名 性別 出生年月 學院  密碼   學號/工號   讀者類型 賬戶餘額 借書數 超期圖書數:\n");

if(head==NULL)

{

head=(struct readerinf*)malloc(LEN);

scanf("%s %s %s %s %s %d %s %d %d %d",

head->name,head->sex,head->birthday,head->college,head->secretnum,

&head->ID,head->type,&head->balance,&head->bornum,&head->outdatenum);

head->next=NULL;

for(j=0;head->secretnum[j]!='\0';j++)

head->secretnum[j]=(head->secretnum[j]-20)*2;

printf("添加成功!\n");

}

else

{

p3=head;                    /*每次添加一本圖書,不用多輸入數據以判斷添加是否結束*/

while(p3->next!=NULL)

p3=p3->next;            /*找到鏈表末尾節點*/

p=(struct readerinf*) malloc(LEN);

p->next=NULL;

scanf("%s %s %s %s %s %d %s %d %d %d",

p->name,p->sex,p->birthday,p->college,p->secretnum,

&p->ID,p->type,&p->balance,&p->bornum,&p->outdatenum);

for(j=0;p->secretnum[j]!='\0';j++)

p->secretnum[j]=(p->secretnum[j]-20)*2;

p3->next=p;                /*將p連接到鏈表末尾節點之後*/

printf("添加成功!\n");

}

return(head);                    /*因爲有空鏈表的情況,頭指針可能改變,所以需要返回值*/

}

/*

函數功能:刪除用戶

輸入/輸出參數:均爲鏈表頭指針head

函數流程:

    1.輸入要刪除用戶的ID

2.若爲頭指針的用戶,則使後一個節點爲頭節點

3.否則尋找該用戶

4.若找到該用戶,則刪除該節點

5.否則向用戶輸出“無此用戶”

*/

struct readerinf *delperson(struct readerinf *head)          

{

int n;

struct readerinf *p,*p3;

printf("請輸入要刪除用戶的ID\n");

scanf("%d",&n);

if(head->ID==n)

head=head->next;

else

{

p3=head;

while(p3->ID!=n&&p3->next!=NULL)

{

p=p3;

p3=p3->next;

}

if(p3->ID==n)

{

p->next=p3->next;

printf("刪除成功!\n");

}

else

printf("無此用戶\n");

}

return(head);                     /*因爲存在頭指針改變的情況,所以需要返回值*/

}

/*

函數功能:查看用戶信息

輸入參數:head--鏈表頭指針

函數流程:

    1.輸入要查看用戶的ID

2.尋找該戶

3.若找到該用戶,則輸出該用戶信息

4.查找所借圖書信息並輸出

5.否則向用戶輸出“無此用戶”

*/

void showperson(struct readerinf *head)         

{

int n,m,i,j;

char a[10];

struct readerinf *p;

struct bookinf *b,*b1;

b=begin();

p=head;

printf("請輸入要查看用戶的ID\n");

scanf("%d",&n);

while(p->ID!=n&&p->next!=NULL)

p=p->next;

if(p->ID==n)

{

strcpy(a,p->secretnum);

for(j=0;a[j]!='\0';j++)

a[j]=(a[j]/2+20);

m=p->bornum;

printf("姓名 性別 出生年月 學院  密碼 學號/工號  讀者類型 賬戶餘額 借書數 超期圖書數:\n");

printf("%s  %s  %s  %s %s  %d   %s       %d       %d       %d\n",

p->name,p->sex,p->birthday,p->college,a,p->ID,

p->type,p->balance,p->bornum,p->outdatenum);

printf("所借圖書信息:\n");

printf("書名 作者 出版社 出版時間 價格 圖書編號 分類 是否在架 借閱次數 超期時間\n");

for(i=0;i<m;i++)

{

b1=b;

while(b1->ISBN!=p->b[i].book&&b1->next!=NULL)

b1=b1->next;

printf("%s %s %s %s %d %d %s %d %d %d年%d月%d日\n",

b1->name,b1->author,b1->pubcompany,

b1->pubdate,b1->price,b1->ISBN,

b1->category,b1->condition,b1->borrowednum,

p->b[i].outyear,p->b[i].outmonth,p->b[i].outday);

}

else

printf("無此用戶\n");

}

/*

函數功能:清空用戶密碼

輸入參數:head--鏈表頭指針

*/

void delsecret(struct readerinf *head)        

{

int n;

struct readerinf *p;

p=head;

printf("請輸入清空密碼用戶的ID\n");

scanf("%d",&n);

while(p->ID!=n&&p->next!=NULL)

p=p->next;

if(p->ID==n)

strcpy(p->secretnum, "8888");/*實際密碼爲0000*/

else

printf("無此用戶\n");

}

/*

函數功能:將鏈表中讀者信息存至文件

*/

void storagereader(struct readerinf *p)          

{

int n=1,i=0;

pf=fopen("reader.txt","w+");

while(p!=NULL)

{

if(n!=1)

fprintf(pf,"\n");

fprintf(pf,"%s %s %s %s %s %d %s %d %d %d",

p->name,p->sex,p->birthday,p->college,p->secretnum,

p->ID,p->type,p->balance,p->bornum,p->outdatenum);

for(i=0;i<(p->bornum);i++)/*依據所借圖書數目,將被借圖書簡單信息存至文件*/

{

fprintf(pf," %d %d %d %d %d",p->b[i].book,p->b[i].outyear,

p->b[i].outmonth,p->b[i].outday,p->b[i].tim);/*此處輸出格式前必須加個空格*/

}

n++;

p1=p;

p=p->next;

free(p1);

}

fclose(pf);

}

/*以下是對圖書管理員模塊使用函數的定義*/


/*

函數功能:圖書管理員登陸

輸出參數:1--登陸成功,0--返回上層

函數流程:

1. 輸入用戶名,若返回上層輸入4

2. 若有這個用戶,則繼續輸入密碼。密碼正確則返回1,

3. 否則繼續輸入。

*/

int loadtwo()                                         

{

int i=0,j=1,n=0,z1;

char c;

printf("返回上層請按4\n");

printf("請輸入用戶名\n");

scanf("%d",&z1);

if(fh1==z1)

return(0);

while(liber[i].z!=z1&&i<5)

i++;

if(liber[i].z==z1)

{

printf("請輸入密碼\n");

while(n!=j)

{

n=0;

for(j=0;liber[i].m[j]!='\0';j++)

{

c=getch();

if(liber[i].m[j]==(c-20)*2)

n++;

}

if(n!=j)

printf("您輸入的密碼有誤\n");

}

return(1);

}

else

{

printf("用戶不存在\n");

return(0);

}

}

/*

函數功能:圖書管理員選擇對應功能,進行操作

*/

void managementtwo()                                  

{

int choice=0;

head2=begin();

while(choice!=fh1)

{

printf("+++++++++++++++++++++++++++++++++++++++++\n");

printf("添加圖書請按0\n");

printf("刪除圖書請按1\n");

printf("修改圖書信息請按2\n");

printf("用戶充值請按3\n");

printf("返回上層請按4\n");

printf("請輸入0--4,其他指令不可用。\n");

scanf("%d",&choice);

switch (choice)

{

case 0:head2=addbook(head2);break;

case 1:head2=delbook(head2);break;

case 2:rewritebook(head2);break;

case 3:head1=creat();recharge(head1);storagereader(head1);break;

case 4:choice=4;break;

default : printf("沒有對應的系統指令,請查證重輸\n");break;

}

}

storagebook(head2);

}

/*

函數功能:添加圖書

輸入/輸出參數:均爲鏈表指頭針head

函數流程:

    1.若鏈表爲空,申請一塊空間給頭指針

2.否則申請一塊空間給p

3.輸入圖書的信息

4.將p指向的節點連到鏈表上

*/

struct bookinf *addbook(struct bookinf *head)      

{

struct bookinf *b,*b3;

printf("請輸入要添加圖書的信息\n");

printf("書名 作者 出版社 出版時間 價格 圖書編號 分類 是否在架 借閱次數:\n");

if(head==NULL)

{

head=(struct bookinf*)malloc(LON);

scanf("%s %s %s %s %d %d %s %d %d",

head->name,head->author,head->pubcompany,head->pubdate,&head->price,

&head->ISBN,head->category,&head->condition,&head->borrowednum);

head->next=NULL;

printf("添加成功!\n");

}

else

{

b3=head;                 /*如此處理可以省去free語句,也不用多輸入數據以判斷添加是否結束*/

b=(struct bookinf*) malloc(LON);

b->next=NULL;

scanf("%s %s %s %s %d %d %s %d %d",

b->name,b->author,b->pubcompany,b->pubdate,&b->price,

&b->ISBN,b->category,&b->condition,&b->borrowednum);

while(b3->next!=NULL)

b3=b3->next;  

b3->next=b;

printf("添加成功!\n");

}

return(head);/*因爲有空鏈表的情況,頭指針可能改變,所以需要返回值*/

}

/*

函數功能:刪除圖書

輸入/輸出參數:均爲鏈表頭指針head

函數流程:

    1.輸入要刪除圖書的ISBN

2.若爲頭指針的圖書,則使後一個節點爲頭節點

3.否則尋找該圖書

4.若找到該圖書,則刪除該節點

5.否則向用戶輸出“無此圖書”

*/

struct bookinf *delbook(struct bookinf *head)        

{

int n;

struct bookinf *b,*b3;

printf("請輸入要刪除圖書的ISBN\n");

scanf("%d",&n);

if(head->ISBN==n)

head=head->next;

else

{

b3=head;

while(b3->ISBN!=n&&b3->next!=NULL)

{

b=b3;

b3=b3->next;

}

if(b3->ISBN==n)

{

b->next=b3->next;

printf("刪除成功!\n");

}

else

printf("無此圖書\n");

}

return(head);/*因爲存在頭指針改變的情況,所以需要返回值*/

}

/*

函數功能:修改圖書信息

輸入參數:head--鏈表頭指針

函數流程:

    1.輸入要修改圖書的ISBN

2.尋找該圖書

3.若找到該圖書,則輸入修改信息

4.否則向用戶輸出“無此圖書”

*/

void rewritebook(struct bookinf *b)                

{

int n;

char a[31],au[21],c[30],d[20];

printf("請輸入要修改圖書的ISBN\n");

scanf("%d",&n);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(b->ISBN==n)

{

printf("請輸入要修改圖書的全部信息\n");

printf("書名 作者 出版社 出版時間 價格 圖書編號 分類 是否在架 借閱次數:\n");

scanf("%s %s %s %s %d %d %s %d %d",

a,b,c,d,&b->price,&b->ISBN,b->category,

&b->condition,&b->borrowednum);

strcpy(b->name,a);

strcpy(b->author,au);

strcpy(b->pubcompany,c);

strcpy(b->pubdate,d);

}

else

printf("無此圖書\n");

}

/*

函數功能:用戶充值

*/

void recharge(struct readerinf *p)                 

{

int n,m;

printf("請輸入要充值用戶的ID\n");

scanf("%d",&n);

while(p->ID!=n&&p->next!=NULL)

p=p->next;

if(p->ID==n)

{

printf("請輸入要充值數額\n");

scanf("%d",&m);

p->balance=p->balance+m;

printf("充值成功!\n");

}

else

printf("無此用戶\n");

}



/*以下是對讀者模塊函數使用的定義*/



/*

函數功能:讀者登陸

輸出參數:1--登陸成功,0--返回上層

函數流程:

    1.打開用戶信息文件,存至鏈表

2. 輸入用戶名,若返回上層輸入4

3. 若有這個用戶,則繼續輸入密碼。密碼正確則返回1,

4. 否則繼續輸入。

*/

struct readerinf * loadthree()                 

{

int i=0,j=1,n=0;

char c;

struct readerinf *p;

head1=creat();

p=head1;

printf("返回上層請按4\n");

printf("請輸入用戶ID\n");

scanf("%d",&n);

if(fh1==n)

return(NULL);

while(p->ID!=n&&p->next!=NULL)

p=p->next;

if(p->ID==n)

{

printf("請輸入密碼\n");

while(n!=j)

{

n=0;

for(j=0;p->secretnum[j]!='\0';)

{

c=getch();

if(p->secretnum[j]==(c-20)*2)

n++;

j++;

}

if(n!=j)

printf("您輸入的密碼有誤\n");

}

return(p);

}

else

{

printf("用戶不存在\n");

return(NULL);

}

}

/*

函數功能:讀者選擇對應功能,進行操作

*/

void operation()                                   

{

int choice=0;                                /*p1爲讀者登錄後對應的指針*/

while(choice!=fh1)

{

printf("+++++++++++++++++++++++++++++++++++++++++\n");

printf("借書請按1\n");

printf("續借請按2\n");

printf("還書請按3\n");

printf("返回請按4\n");

printf("查尋圖書請按5\n");

printf("修改讀者信息請按6\n");

scanf("%d",&choice);

switch (choice)

{

case 1:head2=begin();borrowbook(head2,p1);storagebook(head2);break;

case 2:renewbook(p1);break;

case 3:returnbook(p1);break;

case 4:choice=4;break;

case 5:head2=begin();checkbook(head2);storagebook(head2);break;

case 6:rewritereader(p1);break;

default : printf("沒有對應的系統指令,請查證重輸\n");break;

}

}

storagereader(head1);/*如果參數爲p1則會出錯,head1在loadthree()中已經被賦值*/

}

/*

函數功能:讀取圖書文件中的信息,存至鏈表中

輸出參數:head--鏈表頭指針

函數流程:

    1.打開文件

2.文件沒有結束則讀取文件信息並存至鏈表

3.文件結束則返回頭指針

*/

struct bookinf *begin(void)                         

{   

struct bookinf *head;

pb=fopen("book.txt","r+");

if(pb==NULL)

{

printf("不能打開文件\n");

exit(0);

}

if(pb==-1)

head=NULL;

else

{

b2=(struct bookinf*)malloc(LON);

fscanf(pb,"%s %s %s %s %d %d %s %d %d",

b2->name,b2->author,b2->pubcompany,b2->pubdate,&b2->price,

&b2->ISBN,b2->category,&b2->condition,&b2->borrowednum);

head=b2;

while(!feof(pb))

{

b1=(struct bookinf*)malloc(LON);

fscanf(pb,"%s %s %s %s %d %d %s %d %d",

b1->name,b1->author,b1->pubcompany,b1->pubdate,&b1->price,

&b1->ISBN,b1->category,&b1->condition,&b1->borrowednum);

b2->next=b1;

b2=b1;

}

b2->next=NULL;

fclose(pb);

}

return(head);

}

/*

函數功能:借書

輸入參數:b1--圖書頭指針,p--登陸後讀者指針

函數流程:

    1.讀取系統時間

2.判斷讀者類型

3.若爲學生可以借10本,教師可以借30本

4.判斷所借圖書數是否到達上限

5.若沒有則輸入要借圖書ISBN,否則不允許借

6.查找圖書

7.若有該書則借閱,若沒有則告訴讀者沒有該書

*/

void borrowbook(struct bookinf *b1,struct readerinf *p)                /*借書*/

{

struct bookinf *b;

int n,m;

struct tm *t;

time_t tt;

time(&tt);

t=localtime(&tt);

tt=mktime(t);

b=b1;

if(strcmp(p->type,"學生")==0)

{

if(p->bornum<10)

{

printf("請輸入要借圖書的ISBN\n");

scanf("%d",&n);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(b->ISBN==n)

{

if(b->condition=1)

{

b->condition=0;

b->borrowednum++;

m=p->bornum;

p->bornum++;

p->b[m].book=n;

p->b[m].tim=tt+2592000;

p->b[m].outday=t->tm_mday;

if(t->tm_mon+1==12)

{

p->b[m].outyear=(t->tm_year+1901);

p->b[m].outmonth=1;

}

else

{

p->b[m].outyear=(t->tm_year+1900);

p->b[m].outmonth=t->tm_mon+2;

}

printf("借閱成功!\n");

}

else

printf("該圖書已經被借\n");

}

else

printf("無此圖書\n");

}

else

printf("您的借書書已達上限,不能再借\n");

}

else

{

if(p->bornum<30)

{

printf("請輸入要借圖書的ISBN\n");

scanf("%d",&n);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(b->ISBN==n)

{

if(b->condition=1)

{

b->condition=0;

b->borrowednum++;

m=p->bornum;

p->bornum++;

p->b[m].book=n;

p->b[m].outday=t->tm_mday;

p->b[m].tim=tt+2592000*5;

if(t->tm_mon+1>7)

{

p->b[m].outyear=t->tm_year+1901;

p->b[m].outmonth=(t->tm_mon-6);/*經過數學推導得到的公式*/

}

else

{

p->b[m].outyear=t->tm_year+1900;

p->b[m].outmonth=t->tm_mon+6;

}

printf("借閱成功!\n");

}

else

printf("該圖書已經被借\n");

}

else

printf("無此圖書\n");

}

else

printf("您的借書書已達上限,不能再借\n");

}

}

/*

函數功能:續借

輸入參數:p--登陸後讀者指針

函數流程:

    1.讀取系統時間

2.判斷讀者類型

3.若爲學生則超期時間加1個月份,教師則超期時間加5個月份

4.輸入要續借圖書ISBN號

5.查找該圖書

6.若找到,則按3處理。

7.否則輸出“未藉此書”

*/

void renewbook(struct readerinf *p)                  

{

int n,d;

time_t tt;

struct tm *t;

struct bookinf *b;

b=begin();

time(&tt);

t=localtime(&tt);

tt=mktime(t);

if(strcmp(p->type,"學生")==0)

{

printf("請輸入要續借借圖書的ISBN\n");

scanf("%d",&n);

for(d=0;p->b[d].book!=n&&d<p->bornum;d++);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(p->b[d].book==n)

{

if(b->condition==0)

{

b->condition=2;

p->outdatenum--;

if(p->b[d].outmonth==12)

{

p->b[d].outyear++;

p->b[d].outmonth=1;

}

else

p->b[d].outmonth++;

p->b[d].tim=tt+2592000;

printf("續借成功!\n");

}

else

printf("已經續借過一次不能再借\n");

}

else

printf("未藉此圖書\n");

}

else

{

printf("請輸入要續借借圖書的ISBN\n");

scanf("%d",&n);

for(d=0;p->b[d].book!=n&&d<p->bornum;d++);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(p->b[d].book==n)

{

if(b->condition==0)

{

b->condition=2;

if(p->b[d].outmonth>7)

{

p->b[d].outyear++;

p->b[d].outmonth-=7;/*經過數學推導得到的公式*/

}

else

p->b[d].outmonth+=5;

p->b[d].tim=tt+2592000*5;

printf("續借成功!\n");

}

else

printf("已經續借過一次不能再借\n");

}

else

printf("未藉此圖書\n");

}

}  

/*

函數功能:還書

輸入參數:p--讀者登陸後對應指針

函數流程:

    1.輸入要還圖書ISBN

2.查找該圖書

3.若借了該書被借圖書數減1,並判斷是否超期

4.若超期則使超期圖書數減1

5.調整被借圖書數組b[30];

6.若沒借該書,則輸出“未藉此圖書”

*/

void returnbook(struct readerinf *p)                 

{

int n,d,m;

struct tm *t;

struct bookinf *b;

time_t tt;

b1=b=begin();

time(&tt);

t=localtime(&tt);

printf("請輸入要還圖書的ISBN\n");/*因爲有些書的數目不爲一,防止出錯*/

scanf("%d",&n);

for(d=0;p->b[d].book!=n&&d<p->bornum;d++);

while(b->ISBN!=n&&b->next!=NULL)

b=b->next;

if(p->b[d].book==n)

{

b->condition=1;        /*若滿足上述條件,該書肯定存在*/

p->bornum=p->bornum-1;

if((t->tm_year+1900+(t->tm_mon+1)/12.0)==(p->b[d].outyear+(p->b[d].outmonth)/12.0))  /*調整超期圖書數*/

{

if(p->b[d].outday<t->tm_mday)

p->outdatenum--;

}

if((t->tm_year+1900+(t->tm_mon+1)/12.0)>(p->b[d].outyear+(p->b[d].outmonth)/12.0))

p->outdatenum--;

m=p->bornum;

for(;d<m;d++)      /*調整被借圖書數組*/

{

p->b[d].book=p->b[d+1].book;

p->b[d].outday=p->b[d+1].outday;

            p->b[d].outmonth=p->b[d+1].outmonth;

p->b[d].outyear=p->b[d+1].outyear;

p->b[d].tim=p->b[d+1].tim;

}

p->b[m].book=0;

p->b[m].outday=0;

p->b[m].outmonth=0;

p->b[m].outyear=0;

p->b[m].tim=0;

printf("還書成功!\n");

}

else

printf("未藉此圖書\n");

storagebook(b1);

}

/*

函數功能:查找圖書

*/

void checkbook(struct bookinf *b)                  

{

char a[31],n=0;

printf("請輸入要查找圖書的書名:");

scanf("%s",a);

while(b!=NULL)/*因爲有某本書的數目大於1的情況*/

{

if(strcmp(b->name,a)==0)

{

printf("書名 作者 出版社 出版時間 價格 圖書編號 圖書分類 是否在架 借閱次數\n");

printf("%s %s %s %s %d %d %s %d %d\n",

b->name,b->author,b->pubcompany,

b->pubdate,b->price,b->ISBN,

b->category,b->condition,b->borrowednum);

n=1;

}

b=b->next;

}

if(n==0)

printf("無此圖書\n");

}

/*

函數功能:修改讀者信息

*/

void rewritereader(struct readerinf *p3)            

{

struct readerinf *p;

char a[30],b[4],c[20],d[20],e[10];

long int n;

p=p3;

printf("請輸入所要修改的信息\n");

printf("姓名 性別 出生年月 學院 密碼 學號:\n");/*按實際情況讀者只能修改一部分信息*/

scanf("%s %s %s %s %s %s %d",a,b,c,d,e,&n);

strcpy(p->name,a);

strcpy(p->sex,b);

strcpy(p->birthday,c);

strcpy(p->college,d);

strcpy(p->secretnum,e);

p->ID=n;

}

/*

函數功能:將鏈表中的圖書信息存至文件

*/

void storagebook(struct bookinf *b)                

{

int n=1;

pb=fopen("book.txt","w+");

while(b!=NULL)

{

if(n!=1)

fprintf(pb,"\n");

fprintf(pb,"%s %s %s %s %d %d %s %d %d",

b->name,b->author,b->pubcompany,

b->pubdate,b->price,b->ISBN,

b->category,b->condition,b->borrowednum);

n++;

b1=b;

b=b->next;

free(b1);

}

fclose(pb);

}

/*

函數功能:超期罰款函數

函數流程:

    1.調用函數打開文件

    2.讀取系統時間

3.若圖書到期,將tt賦值給p->b[i].tim,超期圖書數加1

4.若圖書超期,將tt賦值給p->b[i].tim,根據公式p->balance-=(tt-p->b[i].tim)/864000罰款

5.調用函數,存儲信息

*/

/*最好系統每天都能運行一次,如果在圖書超期後才運行系統,則用戶餘額會出現一些小問題。

按實際情況不會時隔那麼久纔再次運行系統,故此隱性問題忽略*/

void fine()                     

{

int i;

struct readerinf *p,*p2;

struct tm *t;

time_t tt;

time(&tt);

t=localtime(&tt);

p2=creat();

p=p2;

tt=mktime(t);

while(p!=NULL)

{

for(i=0;i<p->bornum;i++)

{

if((t->tm_year+1900+(t->tm_mon+1)/12.0)==(p->b[i].outyear+(p->b[i].outmonth)/12.0))

{

if(t->tm_mday==p->b[i].outday)/*到期了*/

{

p->outdatenum++;

p->b[i].tim=tt;

}

if(t->tm_mday>p->b[i].outday)/*超期了*/

{

p->balance-=(tt-p->b[i].tim)/864000;

p->b[i].tim=tt;

}

}

if((t->tm_year+1900+(t->tm_mon+1)/12.0)>(p->b[i].outyear+(p->b[i].outmonth)/12.0))/*超期了*/

{

p->balance-=(tt-p->b[i].tim)/864000;

p->b[i].tim=tt;

}

};

p=p->next;

}

storagereader(p2);

}

/*

函數功能:統計最受喜歡圖書

*/

void statistic()                                   

{

int n=0;                                        

struct bookinf *b,*b1,*bhead;

bhead=b=begin();

while(b!=NULL)

{

if(b->borrowednum>n)

{

n=b->borrowednum;/*記錄最受歡迎圖書的被借次數和地址*/

b1=b;

}

b=b->next;

}

printf("以下是最受喜歡的圖書的信息:\n");

printf("書名    作者    出版社     出版時間   價格  分類 借閱次數\n");

printf("%s %s %s %s %d %s %d\n",

b1->name,b1->author,b1->pubcompany,

b1->pubdate,b1->price,b1->category,n);

storagebook(bhead);

}

/*因爲考慮某本書的數目大於1的情況實在複雜,認爲ISBN號不同即爲不同的圖書*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章