您好,登錄后才能下訂單哦!
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 fh2=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(fh2==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!=fh2)
{
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(fh2==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!=fh2)
{
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(fh2==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!=fh2)
{
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號不同即為不同的圖書*/
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。