全部实现代码如下:
--------------------------------------------------------------------------------------
main.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
void first_main()
{
FILE *fp_book,*fp_reader;
if((fp_book=fopen("Book.txt","r+"))==NULL && (fp_reader=fopen("Reader.txt","r+"))==NULL)
{
about();
Init();
}
else
{
Load();
printf("\t读者及图书信息加载完毕。\n");
//algo43_main();
printf("\t关键词检索表更新完毕。\n");
}
Menu_select();
}//end"first_main()"
int main(void)
{
first_main();
return 0;
}
-----------------------------------------------------------------------------------------------
first.h
#ifndef FIRSTH1
#define FIRSTH1
// #include
// #include
// #include
#include
#define Max 3
typedef struct book
{
char book_num[10];
char book_name[20];
int
book_kc;
//MY库存总量
int
book_xc;
//MY现存数量
struct book *next;
}BK;
typedef struct Start
{
int st_sec;
int st_hour;
int st_mday;
int st_min;
int st_mon;
int st_year;
}start;
typedef struct borrow
{
char borrow_book_num[10];
start lend_t;
}BO;
typedef struct reader
{
char reader_num[10];
char reader_name[10];
int right;
//MY读者最多借书本数
BO borrow[Max];
struct reader * next;
}RD;
//BK *h_book;
//RD *h_reader;
int Menu();
void Menu_select();
void Init();
void Init_reader();
void Init_book();
void Insert_New_Book();
void Insert_New_Reader();
void del_old_book();
void del_old_reader();
void book_not_enough();
int Find();
void Find_Select();
void Find_Reader();
void Find_Book_contral();
int Find_Book_select();
void Find_Book();
void Borrow_Book();
void Return_Book();
void about();
int Print();
void Print_Select();
void Print_book();
void Print_reader();
void Save();
void Save_Reader();
void Save_Book();
void Load();
void Load_Reader();
void Load_Book();
#endif
-------------------------------------------------------------------------------------------------
first.cpp
#include "c1.h"
#include "algo4-3.h"
#include "first.h"
//函数及结构体申明在first.h中
BK *h_book;
RD *h_reader;
int Menu()
{
//int sn;
int sn=-1;
printf("\n\t\t图书管理系统主菜单\n");
printf("==========================================================\n");
printf("*\t0----退出系统
6----关于系统
\t*\n");
printf("*\t1----新书入库
7----旧书出库
\t*\n");
printf("*\t2----增新读者
8----注销读者
\t*\n");
printf("*\t3----查询图书/读者
9----输出全部信息\t*\n");
printf("*\t4----借书登记
10----库存不足图书\t*\n");
printf("*\t5----还书管理
11----保存当前信息\t*\n");
printf("==========================================================\n");
printf("请选择相应代码:");
for(;;)
{
fflush(stdin);
scanf("%d",&sn);
getchar();
if(sn<0||sn>11)
printf("\n错误!请重新输入:");
else break;
}
return sn;
}//"Menu()"end
void Menu_select()
{
char i='n';
for(;;)
{
switch(Menu())
{
case 0:
//char i='n';
printf("是否保存当前更改 y/n?");
scanf("%c",&i);
getchar();
if( i=='y')
{
system("cls");
Save();
printf("\n\n\t文件保存成功!\n");
printf("\n\n\tGoodBye!\n");
getchar();
}
else
printf("\n\n\t放弃文件保存!\n");
getchar();
exit(0);
case 1:Insert_New_Book();break;
case 2:Insert_New_Reader();break;
case 3:Find_Select();break;
case 4:Borrow_Book();break;
case 5:Return_Book();break;
case 6:about();break;
case 7:del_old_book();break;
case 8:del_old_reader();break;
case 9:Print_Select();break;
case 10:book_not_enough();break;
case 11:Save(); Load();
printf("\n文件保存成功!按任意键进行下步操作....");
getchar(); system("cls");break;
default:printf("\n输入错误,请重新输入!"); break ;
}
}//"switch(Menu())"
}//"Menu_select()"end
void Init()
{
Init_reader();
Init_book();
}//"Init()" end
void Init_reader()
{
RD *p0=NULL;
int i;
printf("\n读者初始化开始,请输入读者信息..\n包括编号.姓名..\n");
p0=(RD *)malloc(sizeof(RD));
h_reader=p0;
printf("\n请输入读者的信息:\n");
printf("ReaderNo.:");
scanf("%s",p0->reader_num);
getchar();
printf("ReaderName:");
gets(p0->reader_name);
p0->right=0;
for(i=0;i
strcpy(p0->borrow[i].borrow_book_num,"0");
p0->next=NULL;
p0=NULL;
printf("\n读者信息初始化完毕!按任意键继续下一步操作..\n");
getchar();
system("cls");
}//"Init_reader()" end
void Init_book()
{
BK *p0=NULL;
printf("\n图书初始化开始,请输入图书信息..\n包括编号.书名.数量..\n");
p0=(BK *)malloc(sizeof(BK));
h_book=p0;
printf("\n请输入图书信息:\n");
printf("BookNo.:");
scanf("%s",p0->book_num);
getchar();
printf("BookName:");
gets(p0->book_name);
printf("Number:");
scanf("%d",&p0->book_kc);
getchar();
p0->book_xc=p0->book_kc;
p0->next=NULL;
p0=NULL;
printf("\n图书信息初始化完毕!按任意键继续下一步操作..\n");
getchar();
system("cls");
}//"Init_book()" end
void Insert_New_Reader()
{
RD *p=NULL,*p0=NULL,*p1=NULL,*p2=NULL;
int i;
p=p1=p2=h_reader;
printf("\n增加新读者模块...\n");
printf("\n请输入新读者信息..\n包括编号.姓名..\n");
p0=(RD *)malloc(sizeof(RD));
re_input_reader:
printf("ReaderNo.:");
scanf("%s",p0->reader_num);
while(strcmp(p0->reader_num,p2->reader_num)!=0&&p2->next!=NULL)
p2=p2->next;
if(strcmp(p0->reader_num,p2->reader_num)==0)
{
printf("\n此编号读者已存在!请重新输入\n");
goto re_input_reader;
}
printf("ReaderName:");
scanf("%s",p0->reader_name);
p0->right=0;
for(i=0;i
strcpy(p0->borrow[i].borrow_book_num,"0");
while(strcmp(p->reader_num,p0->reader_num)!=0&&p->next!=NULL)
{
p1=p; p=p->next;
}
if(strcmp(p0->reader_num,p->reader_num)<=0)
{
if(p==h_reader) h_reader=p0;
else p1->next=p0;
p0->next=p;
}
else
{
p->next=p0;
p0->next=NULL;
}
p=NULL;p0=NULL;p1=NULL;p2=NULL;
printf("\n新读者增加完毕!按任意键继续下一步操作..\n");
getchar();
system("cls");
}//"Insert_New_Book()" end
void Insert_New_Book()
{
BK *p=NULL,*p0=NULL,*p1=NULL,*p2=NULL;
p=p1=p2=h_book;
printf("\n新书入库模块...\n");
printf("\n请输入新书信息..\n包括编号.书名.数量..\n");
p0=(BK *)malloc(sizeof(BK));
printf("BookNo.:");
scanf("%s",p0->book_num);
getchar();
while(strcmp(p0->book_num,p2->book_num)!=0&&p2->next!=NULL)
p2=p2->next;
if(strcmp(p0->book_num,p2->book_num)==0)
{
printf("\n此编号图书已存在!!直接入库!\n");
printf("Number:");
scanf("%d",&p0->book_kc);
getchar();
p2->book_kc+=p0->book_kc;
p2->book_xc+=p0->book_kc;
goto end;
}
printf("BookName:");
gets(p0->book_name);
printf("Number:");
scanf("%d",&p0->book_kc);
getchar();
p0->book_xc=p0->book_kc;
while(strcmp(p->book_num,p0->book_num)!=0&&p->next!=NULL)
{
p1=p; p=p->next;
}
if(strcmp(p0->book_num,p->book_num)<=0)
{
if(p==h_book) h_book=p0;
else p1->next=p0;
p0->next=p;
}
else
{
p->next=p0;
p0->next=NULL;
}
end:
algo43_main();
//生成关键字索引表,在algo4-3.cpp中定义
p=NULL;p0=NULL;p1=NULL;p2=NULL;
printf("\n新书入库完毕!按任意键继续下一步操作..\n");
getchar();
system("cls");
}//"Insert_New_Book()" end
int Find()
{
int sn;
printf("\n\t\t打印全部信息菜单\n");
printf("===============================================\n");
printf("*\t0----返回上级
1----关于系统
\t*\n");
printf("*\t
\t*\n");
printf("*\t2----查找图书
3----查找读者
\t*\n");
printf("===============================================\n");
printf("请选择相应代码:");
for(;;)
{
fflush(stdin);
scanf("%d",&sn);
getchar();
if(sn<0||sn>3)
printf("\n错误!请重新输入:");
else break;
}
return sn;
}//"Find()" end
void Find_Select()
{
system("cls");
for(;;)
{
switch(Find())
{
case 0:system("cls"); Menu_select(); break;
case 1:about();break;
case 2:Find_Book_contral();break;
case 3:Find_Reader();break;
default:printf("\n错误!");exit(0);
}
}
}//"Find_Select()"end
int Find_Book_select()
{
int sn;
printf("\n\t\t打印全部信息菜单\n");
printf("=================================================\n");
printf("*\t 0----返回上级
\n");
//MY
1 这条应该改成 关于查询系统 或是 查询帮助
printf("*\t
\t*\n");
printf("*\t 1----编号查询
2----关键字查询\t*\n");
printf("=================================================\n");
printf("请选择相应代码:");
for(;;)
{
fflush(stdin);
scanf("%d",&sn);
getchar();
if(sn<0||sn>3)
printf("\n错误!请重新输入:");
else break;
}
return sn;
}//"Find_Book_select()"end
void Find_Book_contral()
{
system("cls");
for(;;)
{
switch( Find_Book_select() )
{
case 0:system("cls"); Find_Book_select(); break;
case 1:Find_Book();break;
case 2:algo44_main();break;
//algo44_main()algo4-4.cpp中定义
default:printf("\n错误!");exit(0);
}
}
}//"Find_Book_contral()"end
void Find_Book()
{
BK *p=NULL;
char find_book[10];
p=h_book;
printf("\n图书查询模块\n");
printf("\n请输入你要查询图书编号:");
scanf("%s",find_book);
getchar();
while(strcmp(p->book_num,find_book)!=0&&p->next)
p=p->next;
if(strcmp(p->book_num,find_book)==0)
{
printf("\n图书编号:%s的信息为:\n",find_book);
printf("\nBookNo.\t\tBookName\t\t\tXianCun \tKuCun\n");
printf("%s\t\t%s\t\t=\t\t=\n",p->book_num,p->book_name,p->book_xc,p->book_kc);
}
else
printf("\n此图书编号不存在,请核对!按任意键返回...");
p=NULL;
getchar(); system("cls");
}//"Find_Book()"end
void Find_Reader()
{
RD *p=NULL;
int i;
char find_reader[10];
p=h_reader;
printf("\n查询模块\n");
printf("\n请输入你要查询读者编号:");
scanf("%s",find_reader);
getchar();
while(strcmp(p->reader_num,find_reader)!=0&&p->next)
p=p->next;
if(strcmp(p->reader_num,find_reader)==0)
{
printf("\n读者编号:%s的信息为:\n",find_reader);
printf("ReaderNo.\tReaderName");
for(i=0;i
printf("\tBorrowBookNum%d",i+1);
printf("\n");
printf("%s\t\t%s",p->reader_num,p->reader_name);
for(i=0;i
printf("\t\t%7s",p->borrow[i].borrow_book_num);
printf("\n");
}
else
printf("\n此图书编号不存在,请核对!按任意键返回...");
p=NULL;
getchar(); system("cls");
}//"Find_Reader()"end
void Borrow_Book()
{
BK *p=NULL;
RD *q=NULL;
char bo_num[10],rea_num[10];
int i=0,j=0;
p=h_book; q=h_reader;
printf("\n借书模块...\n");
printf("\n请输入借书的读者编号:");
scanf("%s",rea_num);
getchar();
while(q->next!=NULL&&strcmp(rea_num,q->reader_num)!=0)
q=q->next;
if(q->next==NULL&&strcmp(rea_num,q->reader_num)!=0)
{
printf("\n错误!此读者编号不存在!按任意键返回..\n");
goto END;
}
printf("\n请输入你要借的书的编号:");
scanf("%s",bo_num);
getchar();
while(strcmp(bo_num,p->book_num)!=0&&p->next!=NULL)
p=p->next;
if(p->next==NULL&&strcmp(bo_num,p->book_num)!=0)
{
printf("\n错误!此图书编号不存在!按任意键返回..\n");
goto END;
}
if(p->book_xc<=0)
{
printf("\n抱歉,此书已借完!请等待新书的到来!!\n按任意键返回....");
goto END;
}
printf("总共能借%d本,已借%d本\n",Max, q->right+1 );
if(q->right>=Max)
{
printf("\n不好意思,借书数目已满!不能借书!\n按任意键返回....");
goto END;
}
else if(0 != q->right ) //else if(strcmp(q->borrow[0].borrow_book_num,"0")!=0)
{
for(i=0;i
{
if(strcmp(q->borrow[i].borrow_book_num,bo_num)==0)
{
printf("\n抱歉!同一个读者不能同借两本相同的书!\n");
goto END;
}
for(j=0; j
if(strcmp(q->borrow[j].borrow_book_num,"0")==0)
{
time_t timep;
char *wday[]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};
struct tm *pt=NULL;
time(&timep);
pt=localtime(&timep);
printf("借书时间:\n");
printf("\t%d年d月d日",(1900+pt->tm_year),(1+pt->tm_mon),pt->tm_mday);
printf(" %s\n\td:d:d\n",wday[pt->tm_wday],pt->tm_hour,pt->tm_min,pt->tm_sec);
q->borrow[j].lend_t.st_year=(1900+pt->tm_year);
//year
q->borrow[j].lend_t.st_mon=(1+pt->tm_mon);
//month
q->borrow[j].lend_t.st_mday=pt->tm_mday;
//day
//q->borrow[q->right].lend_t->st_wday
星期省略
q->borrow[j].lend_t.st_hour=pt->tm_hour;
//hour
q->borrow[j].lend_t.st_min=pt->tm_min;
//minute
q->borrow[j].lend_t.st_sec=pt->tm_sec;
//second
strcpy(q->borrow[j].borrow_book_num,bo_num);
q->right++;
p->book_xc--;
printf("\n读者编号%s借书完毕!按任意键继续下步操作..",q->reader_num);
goto END;
}//"if(strcmp(q->borrow[i].borrow_book_num,"0")==0)"end
}//"for(i=0;i
}//"else if(strcmp(q->borrow[0].borrow_book_num,"0")!=0)"end
else
{
time_t timep;
char *wday[]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};
struct tm *pt=NULL;
time(&timep);
pt=localtime(&timep);
printf("借书时间:\n");
printf("%d年d月d日",(1900+pt->tm_year),(1+pt->tm_mon),pt->tm_mday);
printf(" %s\nd:d:d\n",wday[pt->tm_wday],pt->tm_hour,pt->tm_min,pt->tm_sec);
q->borrow[q->right].lend_t.st_year=(1900+pt->tm_year);
//year
q->borrow[q->right].lend_t.st_mon=(1+pt->tm_mon);
//month
q->borrow[q->right].lend_t.st_mday=pt->tm_mday;
//day
//q->borrow[q->right].lend_t->st_wday
星期省略
q->borrow[q->right].lend_t.st_hour=pt->tm_hour;
//hour
q->borrow[q->right].lend_t.st_min=pt->tm_min;
//minute
q->borrow[q->right].lend_t.st_sec=pt->tm_sec;
//second
strcpy(q->borrow[q->right++].borrow_book_num,bo_num);
p->book_xc--;
printf("\n读者编号%s借书完毕!按任意键继续下步操作..",q->reader_num);
}//"else"end
END:
p=NULL;
q=NULL;
getchar(); system("cls");
}//"Borrow_Book()"end
void Return_Book()
{
BK *p=NULL;
RD *q=NULL;
int i,j,find=0,day=0;
char return_book_num[10],return_reader_num[10];
p=h_book; q=h_reader;
printf("\n还书模块...\n");
printf("\n请输入要还书的读者编号:");
scanf("%s",return_reader_num);
getchar();
while(q->next!=NULL&&strcmp(return_reader_num,q->reader_num)!=0)
q=q->next;
if(q->next==NULL&&strcmp(return_reader_num,q->reader_num)!=0)
{
printf("\n错误!此读者编号不存在!按任意键返回..\n");
goto End_return_book;
}
printf("\n请输入还书的编号:");
scanf("%s",return_book_num);
getchar();
while(p->next!=NULL&&strcmp(return_book_num,p->book_num)!=0)
p=p->next;
if(p->next==NULL&&strcmp(return_book_num,p->book_num)!=0)
{
printf("\n错误!此图书编号不存在!按任意键返回..\n");
goto End_return_book;
}
for(i=0;i
if(strcmp(return_book_num,q->borrow[i].borrow_book_num)==0)
{
find++;
printf("借书时间:\n");
printf("\t%d年d月d日",q->borrow[i].lend_t.st_year,q->borrow[i].lend_t.st_mon,q->borrow[i].lend_t.st_mday);
printf("\n\td:d:d\n",q->borrow[i].lend_t.st_hour,q->borrow[i].lend_t.st_min,q->borrow[i].lend_t.st_sec);
time_t timep;
//char *wday[]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};
struct tm *pt=NULL;
time(&timep);
pt=localtime(&timep);
printf("还书时间:\n");
printf("\t%d年d月d日",(1900+pt->tm_year),(1+pt->tm_mon),pt->tm_mday);
printf("\n\td:d:d\n",pt->tm_hour,pt->tm_min,pt->tm_sec);
day=( (1900+pt->tm_year) - q->borrow[i].lend_t.st_year)*365;
//year
day+=( (1+pt->tm_mon) - q->borrow[i].lend_t.st_mon )*30;
//month
day+=( pt->tm_mday - q->borrow[i].lend_t.st_mday );
//day
day=( pt->tm_hour - q->borrow[i].lend_t.st_hour ) + day*24;
//hour
day=( pt->tm_min - q->borrow[i].lend_t.st_min ) + day*60;
//minute
day=( pt->tm_sec - q->borrow[i].lend_t.st_sec ) + day*60;
//second
printf("共借阅:%d秒\n",day);
strcpy(q->borrow[i].borrow_book_num,"0");
p->book_xc++;
q->right--;
printf("\n编号%s的读者还书完毕!按任意键继续下步操作..",return_reader_num);
}
if(strcmp(return_book_num,q->borrow[Max-1].borrow_book_num)!=0&&find==0)
printf("\n错误!此读者未借此书!按任意键返回..\n");
End_return_book:
p=NULL;
q=NULL;
getchar(); system("cls");
}//"Return_Book()"end
void del_old_book()
{
BK *p=NULL,*q=NULL;
char del_num[10];
p=h_book;
printf("\n旧书出库模块\n");
printf("\n请输入要出库的图书编号:");
scanf("%s",del_num);
getchar();
while(strcmp(p->book_num,del_num)!=0&&p->next!=NULL)
{ q=p; p=p->next; }
if(strcmp(p->book_num,del_num)==0)
{
if(p->book_kc!=p->book_xc)
printf("\n抱歉,此图书未归还或数据出错,不能出库!按任意键返回...");
else
{
if(p==h_book)
h_book=p->next;
else
q->next=p->next;
free(p);
printf("\n编号为%s的图书删除完毕!按任意键继续...",del_num);
}
}
else
printf("\n你输入的图书编号不存在!按任意键返回...");
p=NULL;
q=NULL;
getchar(); system("cls");
}//"del_old_book()"end
void del_old_reader()
{
RD *p=NULL,*q=NULL;
char del_num[10];
p=h_reader;
printf("\n删除旧读者模块\n");
printf("\n请输入要删除的读者编号:");
scanf("%s",del_num);
getchar();
while(strcmp(p->reader_num,del_num)!=0&&p->next!=NULL)
{ q=p; p=p->next; }
if(strcmp(p->reader_num,del_num)==0)
{
if(strcmp(p->borrow[0].borrow_book_num,"0")!=0)
printf("\n抱歉,此读者还有图书没有归还,不能删除其信息!\n按任意键继续...");
else
{
if(p==h_reader)
h_reader=p->next;
else
q->next=p->next;
free(p);
printf("\n编号为%s的读者删除完毕!按任意键继续...",del_num);
}
}
else
printf("\n你输入的读者编号不存在!按任意键返回...");
p=NULL;
q=NULL;
getchar(); system("cls");
}//"del_old_reader()"end
int Print()
{
int sn;
printf("\n\t\t打印全部信息菜单\n");
printf("=================================================\n");
printf("*\t0----返回上级
1----关于系统
\t*\n");
printf("*\t
\t*\n");
printf("*\t2----打印图书
3----打印读者
\t*\n");
printf("=================================================\n");
printf("请选择相应代码:");
for(;;)
{
fflush(stdin);
scanf("%d",&sn);
getchar();
//fflush(stdin);
if(sn<0||sn>3)
printf("\n错误!请重新输入:");
else break;
}
return sn;
}//"Print()"end
void Print_Select()
{
system("cls");
for(;;)
{
switch(Print())
{
case 0:system("cls"); Menu_select(); break;
case 1:about();break;
case 2:Print_book();break;
case 3:Print_reader();break;
default:printf("\n错误!");exit(0);
}
}
}//"Print_Select()"end
void Print_book()
{
BK *p=NULL;
p=h_book;
printf("\n库存图书信息如下:\n\n");
printf("BookNo.\t\tBookName\t\t\tXianCun \tKuCun\n");
while(p!=NULL)
{
printf("%s\t\t%s\t\t=\t\t=\n",p->book_num,p->book_name,p->book_xc,p->book_kc);
p=p->next;
}
p=NULL;
printf("\n图书信息打印完毕!按任意键继续下一步操作..");
getchar();
system("cls");
}//"Print_book()"end
void Print_reader()
{
RD *p=NULL;
int i;
p=h_reader;
printf("\n库存读者信息如下:\n\n");
printf("ReaderNo.\tReaderName");
for(i=0;i
printf("\tBorrowBookNum%d",i+1);
printf("\n");
while(p!=NULL)
{
printf("%s\t\t%s",p->reader_num,p->reader_name);
for(i=0;i
printf("\t\t%7s",p->borrow[i].borrow_book_num);
printf("\n");
p=p->next;
}
p=NULL;
printf("\n读者信息打印完毕!按任意键继续下一步操作..");
getchar();
system("cls");
}//"Print_reader()"end
void about()
{
system("cls");
printf("\n\n\n\t\t\t关 于 本 系 统 的 说 明\n");
printf("\n\t\t1.本系统为模拟小型图书馆而设计,界面采用数字选择界面.\n");
printf("\n\t\t2.系统初始化时提示用户输入两组信息.\n");
printf("\n\t\t3.初始化完毕后每个读者的借书权限为3本.\n\n\t\t4.读者借书后会在其信息中记录所借书号,未借者书号均为 0.\n");
printf("\n\t\t5.由于时间等原因,系统的其他功能还不健全,望大家见谅!");
printf("\n\n\t\t6.建议:双击可执行文件后,在任务栏那点右键-->属性-->颜色\n\n\t\t
设置屏幕文字为:深蓝色(第10个) 屏幕背景为:淡绿色(第12个)");
printf("\n\n\t\t
具体方法请参看文件夹内Word文档.\n\n\t\t7.系统如有其他问题,请联系作者!");
printf("\n\n\t\t
E-mail:99688385@qq.com");
printf("\n\n\n\t\t阅 读 完 毕, 按 任 意 键 继 续 ...");
getchar(); system("cls");
}//"about()"end
void book_not_enough()
{
BK *p=NULL;
int i=0;
p=h_book;
while(p!=NULL)
{
if(p->book_xc==0)
{
i++;
printf("\n库存不足的图书有:\n");
printf("\nBookNumber\t\tBookName\n");
printf("%s\t\t\t%s\n",p->book_num,p->book_name);
}
p=p->next;
}
if(p==NULL&&i==0)
printf("\n暂时没有库存不足的图书!");
p=NULL;
getchar(); system("cls");
}//"book_not_enough()"end
void Save()
{
Save_Reader();
Save_Book();
}//"Save()"end
void Save_Reader()
{
FILE *fp_reader=NULL;
RD *p=NULL,*p0=NULL;
p=h_reader;
if((fp_reader=fopen("Reader.txt","wb"))==NULL)
{
printf("\n文件保存失败!\n请重新启动本系统...\n");
exit(0);
}
while(p!=NULL)
{
if(fwrite(p,sizeof(RD),1,fp_reader)!=1)
printf("\n写入文件失败!\n请重新启动本系统!\n");
p0=p;
p=p->next;
free(p0);
// Bug 当book.txt 和reader.txt都存在但都为空时,加载信息为空会出现bug,具体原因不解
}
h_reader=NULL;
fclose(fp_reader);
fp_reader=NULL;
p=NULL;
p0=NULL;
}//"Save_Reader()"end
void Save_Book()
{
FILE *fp_book=NULL;
BK *p=NULL,*p0=NULL;
p=h_book;
//(全局指针)
if((fp_book=fopen("Book.txt","wb"))==NULL) // 此处必须用wb将文件全部更新
{
printf("\n文件保存失败!\n请重新启动本系统...\n");
exit(0);
}
while(p!=NULL)
{
if(fwrite(p,sizeof(BK),1,fp_book)!=1)
printf("\n写入文件失败!\n请重新启动本系统!\n");
p0=p;
p=p->next;
free(p0);
}
p=NULL;
p0=NULL;
h_book=NULL;
fclose(fp_book);
fp_book=NULL;
}//"Save_Book()"end
void Load()
{
Load_Reader();
Load_Book();
}//"Load()"end
void Load_Reader()
{
RD *p1=NULL,*p2=NULL,*p3=NULL;
FILE *fp=NULL;
fp=fopen("Reader.txt","rb");
p1=(RD *)malloc(sizeof(RD));
fread(p1,sizeof(RD),1,fp);
h_reader=p3=p2=p1;
while(! feof(fp))
{
p1=(RD *)malloc(sizeof(RD));
fread(p1,sizeof(RD),1,fp);
p2->next=p1;
p3=p2;
p2=p1;
}
p3->next=NULL;
free(p1);
p1=NULL;
p2=NULL;
p3=NULL;
fclose(fp);
fp=NULL;
}//"Load_Reader()"end
void Load_Book()
{
BK *p1=NULL,*p2=NULL,*p3=NULL;
FILE *fp=NULL;
fp=fopen("Book.txt","rb");
p1=(BK *)malloc(sizeof(BK));
fread(p1,sizeof(BK),1,fp);
h_book=p3=p2=p1;
while(! feof(fp))
{
p1=(BK *)malloc(sizeof(BK));
fread(p1,sizeof(BK),1,fp);
p2->next=p1;
p3=p2;
p2=p1;
}
p3->next=NULL;
free(p1);
p1=p2=p3=NULL;
fclose(fp);
fp=NULL;
}//"Load_Book()"end
-------------------------------------------------------------------------------------------------
c4-2.h
#ifndef C4H
#define C4H
// c4-2.h 串的堆分配存储
struct HString
{
char *ch; // 若是非空串,则按串长分配存储区,否则ch为NULL
int length; // 串长度
};
//bo4-2.cpp function
void StrAssign(HString &T,char *chars);
void StrCopy(HString &T,HString S);
Status StrEmpty(HString S);
int StrCompare(HString S,HString T);
int StrLength(HString S);
void ClearString(HString &S);
void Concat(HString &T,HString S1,HString S2);
Status SubString(HString &Sub, HString S,int pos,int len);
void InitString(HString &T);
int Index(HString S,HString T,int pos);
Status StrInsert(HString &S,int pos,HString T);
Status StrDelete(HString &S,int pos,int len);
Status Replace(HString &S,HString T,HString V);// 此函数与串的存储结构无关
void StrPrint(HString T);
#endif
------------------------------------------------------------------------------------------
bo4-2.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
// bo4-2.cpp 串采用堆分配存储结构(由c4-2.h定义)的基本操作(14个)。
//函数及结构体申明在c4-2.h中
#define DestroyString ClearString // DestroyString()与ClearString()作用相同
void StrAssign(HString &T,char *chars)
{ // 生成一个其值等于串常量chars的串T
int i,j;
if(T.ch)
free(T.ch); // 释放T原有空间
i=strlen(chars); // 求chars的长度i
if(!i)
{ // chars的长度为0
T.ch=NULL;
T.length=0;
}
else
{ // chars的长度不为0
T.ch=(char*)malloc(i*sizeof(char)); // 分配串空间
if(!T.ch) // 分配串空间失败
exit(OVERFLOW);
for(j=0;j
T.ch[j]=chars[j];
T.length=i;
}
}
void StrCopy(HString &T,HString S)
{ // 初始条件:串S存在。操作结果:由串S复制得串T
int i;
if(T.ch)
free(T.ch); // 释放T原有空间
T.ch=(char*)malloc(S.length*sizeof(char)); // 分配串空间
if(!T.ch) // 分配串空间失败
exit(OVERFLOW);
for(i=0;i
T.ch[i]=S.ch[i];
T.length=S.length;
}
Status StrEmpty(HString S)
{ // 初始条件:串S存在。操作结果:若S为空串,则返回TRUE,否则返回FALSE
if(S.length==0&&S.ch==NULL)
return TRUE;
else
return FALSE;
}
int StrCompare(HString S,HString T)
{ // 若S>T,则返回值>0;若S=T,则返回值=0;若S<0
int i;
for(i=0;i
if(S.ch[i]!=T.ch[i])
return S.ch[i]-T.ch[i];
return S.length-T.length;
}
int StrLength(HString S)
{ // 返回S的元素个数,称为串的长度
return S.length;
}
void ClearString(HString &S)
{ // 将S清为空串
free(S.ch);
S.ch=NULL;
S.length=0;
}
void Concat(HString &T,HString S1,HString S2)
{ // 用T返回由S1和S2联接而成的新串
int i;
if(T.ch)
free(T.ch); // 释放旧空间
T.length=S1.length+S2.length;
T.ch=(char *)malloc(T.length*sizeof(char));
if(!T.ch)
exit(OVERFLOW);
for(i=0;i
T.ch[i]=S1.ch[i];
for(i=0;i
T.ch[S1.length+i]=S2.ch[i];
}
Status SubString(HString &Sub, HString S,int pos,int len)
{ // 用Sub返回串S的第pos个字符起长度为len的子串。
// 其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1
int i;
if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
return ERROR;
if(Sub.ch)
free(Sub.ch); // 释放旧空间
if(!len) // 空子串
{
Sub.ch=NULL;
Sub.length=0;
}
else
{ // 完整子串
Sub.ch=(char*)malloc(len*sizeof(char));
if(!Sub.ch)
exit(OVERFLOW);
for(i=0;i<=len-1;i++)
Sub.ch[i]=S.ch[pos-1+i];
Sub.length=len;
}
return OK;
}
void InitString(HString &T)
{ // 初始化(产生空串)字符串T。另加
T.length=0;
T.ch=NULL;
}
int Index(HString S,HString T,int pos) // 算法4.1
{ // T为非空串。若主串S中第pos个字符之后存在与T相等的子串,
// 则返回第一个这样的子串在S中的位置,否则返回0
int n,m,i;
HString sub;
InitString(sub);
if(pos>0)
{
n=StrLength(S);
m=StrLength(T);
i=pos;
while(i<=n-m+1)
{
SubString(sub,S,i,m);
if(StrCompare(sub,T)!=0)
++i;
else
return i;
}
}
return 0;
}
Status StrInsert(HString &S,int pos,HString T) // 算法4.4
{ // 1≤pos≤StrLength(S)+1。在串S的第pos个字符之前插入串T
int i;
if(pos<1||pos>S.length+1) // pos不合法
return ERROR;
if(T.length) // T非空,则重新分配空间,插入T
{
S.ch=(char*)realloc(S.ch,(S.length+T.length)*sizeof(char));
if(!S.ch)
exit(OVERFLOW);
for(i=S.length-1;i>=pos-1;--i) // 为插入T而腾出位置
S.ch[i+T.length]=S.ch[i];
for(i=0;i
S.ch[pos-1+i]=T.ch[i]; // 插入T
S.length+=T.length;
}
return OK;
}
Status StrDelete(HString &S,int pos,int len)
{ // 从串S中删除第pos个字符起长度为len的子串
int i;
if(S.length
return ERROR;
for(i=pos-1;i<=S.length-len;i++)
S.ch[i]=S.ch[i+len];
S.length-=len;
S.ch=(char*)realloc(S.ch,S.length*sizeof(char));
return OK;
}
Status Replace(HString &S,HString T,HString V) // 此函数与串的存储结构无关
{ // 初始条件:串S,T和V存在,T是非空串
// 操作结果:用V替换主串S中出现的所有与T相等的不重叠的子串
int i=1; // 从串S的第一个字符起查找串T
if(StrEmpty(T)) // T是空串
return ERROR;
do
{
i=Index(S,T,i); // 结果i为从上一个i之后找到的子串T的位置
if(i) // 串S中存在串T
{
StrDelete(S,i,StrLength(T)); // 删除该串T
StrInsert(S,i,V); // 在原串T的位置插入串V
i+=StrLength(V); // 在插入的串V后面继续查找串T
}
}while(i);
return OK;
}
void StrPrint(HString T)
{ // 输出T字符串。另加
int i;
for(i=0;i
printf("%c",T.ch[i]);
printf("\n");
}
--------------------------------------------------------------------------------
c4-3.h
#ifndef ALGO43H
#define ALGO43H
#include "c2-5.h"
#include "c4-2.h"
typedef int ElemType;
//bo2-6.cpp function
void MakeNode(Link &p,ElemType e);
void FreeNode(Link &p);
void InitList(LinkList &L);
void ClearList(LinkList &L);
void DestroyList(LinkList &L);
void InsFirst(LinkList &L,Link h,Link s); // 形参增加L,因为需修改L
Status DelFirst(LinkList &L,Link h,Link &q); // 形参增加L,因为需修改L
void Append(LinkList &L,Link s);
Position PriorPos(LinkList L,Link p);
Status Remove(LinkList &L,Link &q);
void InsBefore(LinkList &L,Link &p,Link s);
void InsAfter(LinkList &L,Link &p,Link s);
void SetCurElem(Link p,ElemType e);
ElemType GetCurElem(Link p);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Position GetLast(LinkList L);
Position GetHead(LinkList L);
Position NextPos(Link p);
Status LocatePos(LinkList L,int i,Link &p);
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType));
void ListTraverse(LinkList L,void(*visit)(ElemType));
void OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType));
Status LocateElem(LinkList L,ElemType e,Position &q,int(*compare)(ElemType,ElemType));
//algo4-3.cpp
#define MaxKeyNum 25 //索引表的最大容量(关键词的最大数目)
#define MaxLineLen 52 //数目串(也是一个书目中的关键词)的最大数目
#define MaxNoIdx 10
struct WordLisType//一个书目的词表(顺序表)和非索引词表(有序表)共用类型
{
char *item[MaxNoIdx]; //词表(字符串)指针数组
int last; //词的数量
};
struct IdxTermType //索引项类型
{
HString key; //关键词(堆分配类型,c4-2.h)
LinkList bnolist; //存放书号索引的链表(c2-5.h)
};
struct IdxListType //索引表类型(有序表)
{
IdxTermType item[MaxKeyNum+1]; //索引项数组类型
int last; //关键词的个数
};
void InitIdxList(IdxListType &idxlist);
void ExtractKeyWord(int &BookNo);
void GetWord(int i, HString &wd);
int Locate(IdxListType &idxlist, HString wd, Status &b);
void InsertNewKey(IdxListType &idxlist,int i,HString wd);
void InsertBook(IdxListType &idxlist, int i, int bno);
void InsIdxList(IdxListType &idxlist , int bno);
void PutText(FILE *f , IdxListType idxlist);
void algo43_main(void);
//algo4-4.cpp
#define MaxBookNum 10 // 假设只对10个书名建索引表
#define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
struct BookTermType // 书目项类型
{
char bookname[MaxLineLen+1]; // 书名串(包括'\0')
int bookno; // 书号
};
struct BookListType // 书目表类型(有序表)
{
BookTermType item[MaxBookNum]; // 书目项数组类型
int last; // 书目的数量
};
void algo44_main();
#endif
---------------------------------------------------------------------------------
algo4-3.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
//函数及结构体申明在algo4-3.h中
//全局变量
BK bookinfo;//BK * bookinfo=NULL;
char buf[MaxLineLen+1];
WordLisType wdlist,noidx;
//初始化操作,置索引表idxlist为空表,且在idxlist.item[0]设一空串
void InitIdxList(IdxListType &idxlist)
{
idxlist.last=0;
InitString(idxlist.item[0].key); //初始化[0]单元,函数在bo2-4.cpp中
InitList(idxlist.item[0].bnolist); //初始化[0]单元,函数在bo2-6.cpp中
}
void ExtractKeyWord(int &BookNo)
{
int i,l,f=1; //f是字符串buf结束标志0:结束 1:未结束
char *s1=NULL,*s2=NULL;
for(i = 1; i <= wdlist.last; i++)
{
free(wdlist.item[i]); //释放上一个书目在词表wdlist的存储空间
wdlist.item[i]=NULL;
}
wdlist.last=0; // 初始化词表wdlist的词数量
BookNo=atoi(bookinfo.book_num);
s1=buf;//s1=&buf[4];
while(f) //提取书名关键词到词表wdlist
{
s2=strchr(s1, ' '); //s2指向s1后的第一个空格,如没有,返回NULL
if(!s2) //到串尾(没空格)
{
s2=strchr(s1,'\0');//s2=strchr(s1,'\12');
//s2指向buf的最后一个字符(回车符10) MY应该改为'\0'(串结束标志),gets不保存回车符
f=0;
}
l=s2-s1; //单词长度
if(s1[0] >= 'A' && s1[0] <= 'Z') //单词首写字母为大写
{ //写入词表
wdlist.item[wdlist.last]=(char *)malloc((l+1)*sizeof(char));
//生成串空间(包括‘\0’)
for(i = 0; i < l; i++)
wdlist.item[wdlist.last][i]=s1[i]; //写入词表
wdlist.item[wdlist.last][l]=0; // 串结束符‘\0’== 0
for(i =0; i < noidx.last &&(l=strcmp(wdlist.item[wdlist.last],noidx.item[i])) >0 ;i++)
; //查找是否为非索引词
if(!l) //是非索引词
{
free(wdlist.item[wdlist.last]); //从词表中删除该词
wdlist.item[wdlist.last]=NULL;
}
else
wdlist.last++; //词表长度加1
}
s1=s2+1; //s1移动到下一个单词的首字符处
};
s1=NULL;s2=NULL;
}
//用wd返回词表wdlist中的第i个关键词
void GetWord(int i, HString &wd)
{
StrAssign(wd,wdlist.item[i]); //生成关键字字符串 bo2-4.cpp
}
//在索引表idxlist中查询是否存在与wd相等的关键词。若存在,则返回其在索引表中的位置,且b取值TRUE;否则返回插入的位置,且b取值FALSE
int Locate(IdxListType &idxlist, HString wd, Status &b)
{
int i,m;
for(i=idxlist.last; (m = StrCompare(idxlist.item[i].key , wd)) > 0; --i)
; //bo4-2.cpp
if (m == 0) //finded
{
b = TRUE;
return i;
}
else
{
b = FALSE;
return i+1;
}
}
//索引表idxlist的第i项上插入关键词wd,并初始化书号索引的链表为空表
void InsertNewKey(IdxListType &idxlist,int i,HString wd)
{
int j=0;
for (j = idxlist.last; j >= i; --j) //后移索引项
{
idxlist.item[j+1] = idxlist.item[j];
}
InitString(idxlist.item[i].key); //bo4-2.cpp
StrCopy( idxlist.item[i].key , wd); //串拷贝插入新的索引项bo2-4.cpp
InitList(idxlist.item[i].bnolist); //初始化书号索引表为空表 bo2-6.cpp
idxlist.last++;
}
//在索引表idxlist的第i项中插入书号为bno的索引
void InsertBook(IdxListType &idxlist, int i, int bno)
{
Link p;
MakeNode(p , bno); //分配结点 bo2-6.cpp
p->next=NULL;
Append(idxlist.item[i].bnolist , p); //插入新的书号索引 bo2-6.cpp
}
//将新书号为bno的关键词插入索引表
void InsIdxList(IdxListType &idxlist , int bno)
{
int i=0,j=0;
Status b;
HString wd;
InitString(wd);
for(i = 0;i < wdlist.last ; i++)
{
GetWord(i ,wd);
j = Locate(idxlist , wd , b);
if(!b)
{
InsertNewKey(idxlist , j ,wd);
}
InsertBook(idxlist , j , bno);
}
}
//将生成的索引表idxlist输出到文件f
void PutText(FILE *f , IdxListType idxlist)
{
int i=0,j=0;
Link p;
fprintf(f, "%d\n" , idxlist.last);
for (i = 1; i <= idxlist.last; i++)
{
for(j = 0; j < idxlist.item[i].key.length; j++)
fprintf(f, "%c", idxlist.item[i].key.ch[j]);
fprintf(f, "\n%d\n",idxlist.item[i].bnolist.len);
p = idxlist.item[i].bnolist.head;
for(j = 1; j <= idxlist.item[i].bnolist.len; j++)
{
p = p->next;
fprintf( f, "%d ", p->data);
}
fprintf(f, "\n");
}//end "for(i = 1; ...)"
}
void algo43_main(void)
{
FILE *f; // 任何时间最多打开一个文件
IdxListType idxlist; // 索引表
int BookNo; // 书号变量
int k;
if(!(f=fopen("NoIdx.txt","r"))) // 打开非索引词文件
{
printf("Can't open the NoIdx.txt file");
exit(OVERFLOW);
}
fscanf(f,"%d",&noidx.last); // 读取非索引词个数
for(k=0;k
{
fscanf(f,"%s",buf);
if( (noidx.item[k]=(char*)malloc((strlen(buf)+1)*sizeof(char)))==NULL )
{
printf("分配失败!");
exit(1);
}
strcpy(noidx.item[k],buf); //Bug buf的值赋不到noidx.item[k]中
}
fclose(f); // 关闭非索引词文件
if(!(f=fopen("Book.txt","r"))) // 打开书目文件
{
printf("Can't open the Book.txt file");
exit(FALSE);
}
InitIdxList(idxlist); // 设索引表idxlist为空,并初始化[0]单元
fread(&bookinfo,1,sizeof(struct book),f); //fread(buf,1,sizeof(struct book),f);
while(!feof(f))
{
strcpy(buf,bookinfo.book_name);
ExtractKeyWord(BookNo);
InsIdxList(idxlist,BookNo);
fread(&bookinfo,1,sizeof(struct book),f);
}
fclose(f);
f=NULL;
if(!(f=fopen("BookIdx.txt","w"))) // 打开书名关键词索引文件
{
printf("Can't open the BookIdx.txt file");
exit(INFEASIBLE);
}
PutText(f,idxlist); // 将生成的索引表idxlist输出到书名关键词索引文件
fclose(f); // 关闭书名关键词索引文件
}
---------------------------------------------------------------------------------
algo4-3.h
//
algo4-3.cpp 中使用的相关宏定义,bo2-6.cpp中的函数申明
#ifndef ALGO43H
#define ALGO43H
#include "c2-5.h"
#include "c4-2.h"
typedef int ElemType;
//bo2-6.cpp function
void MakeNode(Link &p,ElemType e);
void FreeNode(Link &p);
void InitList(LinkList &L);
void ClearList(LinkList &L);
void DestroyList(LinkList &L);
void InsFirst(LinkList &L,Link h,Link s); // 形参增加L,因为需修改L
Status DelFirst(LinkList &L,Link h,Link &q); // 形参增加L,因为需修改L
void Append(LinkList &L,Link s);
Position PriorPos(LinkList L,Link p);
Status Remove(LinkList &L,Link &q);
void InsBefore(LinkList &L,Link &p,Link s);
void InsAfter(LinkList &L,Link &p,Link s);
void SetCurElem(Link p,ElemType e);
ElemType GetCurElem(Link p);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Position GetLast(LinkList L);
Position GetHead(LinkList L);
Position NextPos(Link p);
Status LocatePos(LinkList L,int i,Link &p);
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType));
void ListTraverse(LinkList L,void(*visit)(ElemType));
void OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType));
Status LocateElem(LinkList L,ElemType e,Position &q,int(*compare)(ElemType,ElemType));
//algo4-3.cpp
#define MaxKeyNum 25 //索引表的最大容量(关键词的最大数目)
#define MaxLineLen 52 //数目串(也是一个书目中的关键词)的最大数目
#define MaxNoIdx 10
struct WordLisType//一个书目的词表(顺序表)和非索引词表(有序表)共用类型
{
char *item[MaxNoIdx];
//词表(字符串)指针数组
int last;
//词的数量
};
struct IdxTermType //索引项类型
{
HString key;
//关键词(堆分配类型,c4-2.h)
LinkList bnolist;
//存放书号索引的链表(c2-5.h)
};
struct IdxListType
//索引表类型(有序表)
{
IdxTermType item[MaxKeyNum+1];
//索引项数组类型
int last;
//关键词的个数
};
void InitIdxList(IdxListType &idxlist);
void ExtractKeyWord(int &BookNo);
void GetWord(int i, HString &wd);
int Locate(IdxListType &idxlist, HString wd, Status &b);
void InsertNewKey(IdxListType &idxlist,int i,HString wd);
void InsertBook(IdxListType &idxlist, int i, int bno);
void InsIdxList(IdxListType &idxlist , int bno);
void PutText(FILE *f , IdxListType idxlist);
void algo43_main(void);
//algo4-4.cpp
#define MaxBookNum 10 // 假设只对10个书名建索引表
#define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
struct BookTermType // 书目项类型
{
char bookname[MaxLineLen+1]; // 书名串(包括'\0')
int bookno; // 书号
};
struct BookListType // 书目表类型(有序表)
{
BookTermType item[MaxBookNum]; // 书目项数组类型
int last; // 书目的数量
};
void algo44_main();
#endif
---------------------------------------------------------------------------------
algo4-4.cpp
//根据algo4-3.cpp产生的文件,索引查询图书
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
//结构体定义和函数声明放在algo4-3.h中
void algo44_main()
{
FILE *f; // 任何时间最多打开一个文件
IdxListType idxlist; // 索引表
BookListType booklist; // 书目表
char buf[MaxLineLen+5]; // 当前书目串(包括书号和'\0')
HString ch; // 索引字符串
int BookNo; // 书号
Link p; // 链表指针
int i,j,k,flag=1; // flag是继续查询的标志
InitString(ch); // 初始化HString类型的变量
if(!(f=fopen("BookIdx.txt","r"))) // 打开书名关键词索引表文件
{
printf("BookIdx.txt can not open!\n");
exit(OVERFLOW);
}
fscanf(f,"%d",&idxlist.last); // 书名关键词个数
for(k=0;k
{
fscanf(f,"%s",buf);
i=0;
while(buf[i])
buf[i++]=tolower(buf[i]); // 字母转为小写
InitString(idxlist.item[k].key);
StrAssign(idxlist.item[k].key,buf);
InitList(idxlist.item[k].bnolist); // 初始化书号链表,bo2-6.cpp
fscanf(f,"%d",&i);
for(j=0;j
{
fscanf(f,"%d",&BookNo);
MakeNode(p,BookNo); // 产生新的书号结点,bo2-6.cpp
p->next=NULL; // 给书号结点的指针域赋值
Append(idxlist.item[k].bnolist,p); // 在表尾插入新的书号结点,bo2-6.cpp
}
}
fclose(f);
if(!(f=fopen("Book.txt","r"))) // 打开书目文件
{
printf("Can not open Book.txt\n");
exit(FALSE);
}
i=0;
while(fgets(buf,MaxLineLen,f))
{ // 把书目文件的内容拷到booklist中
booklist.item[i].bookno=atoi(buf); // 前几位数字为书号
strcpy(booklist.item[i++].bookname,&buf[4]); // 将buf由书名开始的字符串拷贝到booklist中
}
booklist.last=i;
while(flag)
{
printf("请输入书目的关键词(一个):");
scanf("%s",buf);
i=0;
while(buf[i])
buf[i++]=tolower(buf[i]); // 字母转为小写
StrAssign(ch,buf);
i=0;
do
{
k=StrCompare(ch,idxlist.item[i++].key); // bo4-2.cpp
}while(k&&i<=idxlist.last);
if(!k) // 索引表中有此关键词
{
p=idxlist.item[--i].bnolist.head->next; // p指向索引表中此关键词相应链表的首元结点
while(p)
{
j=0;
while(jdata!=booklist.item[j].bookno) // 在booklist中找相应的书号
j++;
if(j
printf("= %s",booklist.item[j].bookno,booklist.item[j].bookname);
p=p->next; // 继续向后找
}
}
else
printf("没找到\n");
printf("继续查找请输入1,退出查找请输入0:");
scanf("%d",&flag);
//getchar();
}
fclose(f);
f=NULL;
getchar(); system("cls");
}
//调整algo44_main()函数的一些地方以适应book.txt文件数据的存放模式
---------------------------------------------------------------------------------
bo2-6.cpp //链表的各种操作函数
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
// bo2-6.cpp 具有实用意义的线性链表(存储结构由c2-5.h定义)的24个基本操作
//函数及结构体申明在algo4-3.h中
void MakeNode(Link &p,ElemType e)
{ // 分配由p指向的值为e的结点。若分配失败,则退出
p=(Link)malloc(sizeof(LNode));
if(!p)
exit(ERROR);
p->data=e;
}
void FreeNode(Link &p)
{ // 释放p所指结点
free(p);
p=NULL;
}
void InitList(LinkList &L)
{ // 构造一个空的线性链表L
Link p;
p=(Link)malloc(sizeof(LNode)); // 生成头结点
if(p)
{
p->next=NULL;
L.head=L.tail=p;
L.len=0;
}
else
exit(ERROR);
}
void ClearList(LinkList &L)
{ // 将线性链表L重置为空表,并释放原链表的结点空间
Link p,q;
if(L.head!=L.tail) // 不是空表
{
p=q=L.head->next;
L.head->next=NULL;
while(p!=L.tail)
{
p=q->next;
free(q);
q=p;
}
free(q);
L.tail=L.head;
L.len=0;
}
}
void DestroyList(LinkList &L)
{ // 销毁线性链表L,L不再存在
ClearList(L); // 清空链表
FreeNode(L.head);
L.tail=NULL;
L.len=0;
}
void InsFirst(LinkList &L,Link h,Link s) // 形参增加L,因为需修改L
{ // h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前
s->next=h->next;
h->next=s;
if(h==L.tail) // h指向尾结点
L.tail=h->next; // 修改尾指针
L.len++;
}
Status DelFirst(LinkList &L,Link h,Link &q) // 形参增加L,因为需修改L
{ // h指向L的一个结点,把h当做头结点,删除链表中的第一个结点并以q返回。
// 若链表为空(h指向尾结点),q=NULL,返回FALSE
q=h->next;
if(q) // 链表非空
{
h->next=q->next;
if(!h->next) // 删除尾结点
L.tail=h; // 修改尾指针
L.len--;
return OK;
}
else
return FALSE; // 链表空
}
void Append(LinkList &L,Link s)
{ // 将指针s(s->data为第一个数据元素)所指(彼此以指针相链,以NULL结尾)的
// 一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新的尾结点
int i=1;
L.tail->next=s;
while(s->next)
{
s=s->next;
i++;
}
L.tail=s;
L.len+=i;
}
Position PriorPos(LinkList L,Link p)
{ // 已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置。若无前驱,则返回NULL
Link q;
q=L.head->next;
if(q==p) // 无前驱
return NULL;
else
{
while(q->next!=p) // q不是p的直接前驱
q=q->next;
return q;
}
}
Status Remove(LinkList &L,Link &q)
{ // 删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点
Link p=L.head;
if(L.len==0) // 空表
{
q=NULL;
return FALSE;
}
while(p->next!=L.tail)
p=p->next;
q=L.tail;
p->next=NULL;
L.tail=p;
L.len--;
return OK;
}
void InsBefore(LinkList &L,Link &p,Link s)
{ // 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前,
// 并修改指针p指向新插入的结点
Link q;
q=PriorPos(L,p); // q是p的前驱
if(!q) // p无前驱
q=L.head;
s->next=p;
q->next=s;
p=s;
L.len++;
}
void InsAfter(LinkList &L,Link &p,Link s)
{ // 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后,
// 并修改指针p指向新插入的结点
if(p==L.tail) // 修改尾指针
L.tail=s;
s->next=p->next;
p->next=s;
p=s;
L.len++;
}
void SetCurElem(Link p,ElemType e)
{ // 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
p->data=e;
}
ElemType GetCurElem(Link p)
{ // 已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值
return p->data;
}
Status ListEmpty(LinkList L)
{ // 若线性链表L为空表,则返回TRUE,否则返回FALSE
if(L.len)
return FALSE;
else
return TRUE;
}
int ListLength(LinkList L)
{ // 返回线性链表L中元素个数
return L.len;
}
Position GetHead(LinkList L)
{ // 返回线性链表L中头结点的位置
return L.head;
}
Position GetLast(LinkList L)
{ // 返回线性链表L中最后一个结点的位置
return L.tail;
}
Position NextPos(Link p)
{ // 已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置。若无后继,则返回NULL
return p->next;
}
Status LocatePos(LinkList L,int i,Link &p)
{ // 返回p指示线性链表L中第i个结点的位置,并返回OK,i值不合法时返回ERROR。i=0为头结点
int j;
if(i<0||i>L.len)
return ERROR;
else
{
p=L.head;
for(j=1;j<=i;j++)
p=p->next;
return OK;
}
}
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType))
{ // 返回线性链表L中第1个与e满足函数compare()判定关系的元素的位置,
// 若不存在这样的元素,则返回NULL
Link p=L.head;
do
p=p->next;
while(p&&!(compare(p->data,e))); // 没到表尾且没找到满足关系的元素
return p;
}
void ListTraverse(LinkList L,void(*visit)(ElemType))
{ // 依次对L的每个数据元素调用函数visit()
Link p=L.head->next;
int j;
for(j=1;j<=L.len;j++)
{
visit(p->data);
p=p->next;
}
printf("\n");
}
void OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType))
{ // 已知L为有序线性链表,将元素e按非降序插入在L中。(用于一元多项式)
Link o,p,q;
q=L.head;
p=q->next;
while(p!=NULL&&comp(p->data,e)<0) // p不是表尾且元素值小于e
{
q=p;
p=p->next;
}
o=(Link)malloc(sizeof(LNode)); // 生成结点
o->data=e; // 赋值
q->next=o; // 插入
o->next=p;
L.len++; // 表长加1
if(!p) // 插在表尾
L.tail=o; // 修改尾结点
}
Status LocateElem(LinkList L,ElemType e,Position &q,int(*compare)(ElemType,ElemType))
{ // 若升序链表L中存在与e满足判定函数compare()取值为0的元素,则q指示L中
// 第一个值为e的结点的位置,并返回TRUE;否则q指示第一个与e满足判定函数
// compare()取值>0的元素的前驱的位置。并返回FALSE。(用于一元多项式)
Link p=L.head,pp;
do
{
pp=p;
p=p->next;
}while(p&&(compare(p->data,e)<0)); // 没到表尾且p->data.expn if(!p||compare(p->data,e)>0) // 到表尾或compare(p->data,e)>0
{
q=pp;
return FALSE;
}
else // 找到
{
q=p;
return TRUE;
}
}
---------------------------------------------------------------------------------
c1.h //常用头文件、宏等的定义
#ifndef HEAD1
#define HEAD1
#include
#include
#include //malloc()等
#include //INT_MAX等
#include //FOF(=^Z或F6),NUll
#include //atoi()
#include //eof()
#include //floor(),ceil(),abs()
#include //exit()
#include //cout,cin
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; //Boolean是布尔类型,其值是TRUE或FALSE
#endif
---------------------------------------------------------------------------------
c2-5.h //链表结点的相关定义
#ifndef C2H
#define C2H
typedef int ElemType;
// c2-5.h 带头结点的线性链表类型
typedef struct LNode // 结点类型
{
ElemType data;
LNode *next;
}*Link,*Position;
struct LinkList // 链表类型
{
Link head,tail; // 分别指向线性链表中的头结点和最后一个结点
int len; // 指示线性链表中数据元素的个数
};
#endif
---------------------------------------------------------------------------------------------
看完代码我自己都怀疑当初是这么实现的,代码繁多。不过回想起来,一个个功能的按部就班的实现也就成了这个摸样。
--------------------------------------------------------------------------------------
main.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
void first_main()
{
}//end"first_main()"
int main(void)
{
}
-----------------------------------------------------------------------------------------------
first.h
#ifndef FIRSTH1
#define FIRSTH1
// #include
// #include
// #include
#include
#define Max 3
typedef struct book
{
}BK;
typedef struct Start
{
}start;
typedef struct borrow
{
}BO;
typedef struct reader
{
}RD;
//BK *h_book;
//RD *h_reader;
int Menu();
void Menu_select();
void Init();
void Init_reader();
void Init_book();
void Insert_New_Book();
void Insert_New_Reader();
void del_old_book();
void del_old_reader();
void book_not_enough();
int Find();
void Find_Select();
void Find_Reader();
void Find_Book_contral();
int
void Find_Book();
void Borrow_Book();
void Return_Book();
void about();
int Print();
void Print_Select();
void Print_book();
void Print_reader();
void Save();
void Save_Reader();
void Save_Book();
void Load();
void Load_Reader();
void Load_Book();
#endif
-------------------------------------------------------------------------------------------------
first.cpp
#include "c1.h"
#include "algo4-3.h"
#include "first.h"
//函数及结构体申明在first.h中
BK *h_book;
RD *h_reader;
int Menu()
{
//int sn;
}//"Menu()"end
void Menu_select()
{
}//"Menu_select()"end
void Init()
{
}//"Init()" end
void Init_reader()
{
}//"Init_reader()" end
void Init_book()
{
}//"Init_book()" end
void Insert_New_Reader()
{
}//"Insert_New_Book()" end
void Insert_New_Book()
{
}//"Insert_New_Book()" end
int Find()
{
}//"Find()" end
void Find_Select()
{
}//"Find_Select()"end
int Find_Book_select()
{
}//"Find_Book_select()"end
void Find_Book_contral()
{
}//"Find_Book_contral()"end
void Find_Book()
{
}//"Find_Book()"end
void Find_Reader()
{
}//"Find_Reader()"end
void Borrow_Book()
{
}//"Borrow_Book()"end
void Return_Book()
{
}//"Return_Book()"end
void del_old_book()
{
}//"del_old_book()"end
void del_old_reader()
{
}//"del_old_reader()"end
int Print()
{
}//"Print()"end
void Print_Select()
{
}//"Print_Select()"end
void Print_book()
{
}//"Print_book()"end
void Print_reader()
{
}//"Print_reader()"end
void about()
{
}//"about()"end
void book_not_enough()
{
}//"book_not_enough()"end
void Save()
{
}//"Save()"end
void Save_Reader()
{
}//"Save_Reader()"end
void Save_Book()
{
}//"Save_Book()"end
void Load()
{
}//"Load()"end
void Load_Reader()
{
}//"Load_Reader()"end
void Load_Book()
{
}//"Load_Book()"end
-------------------------------------------------------------------------------------------------
c4-2.h
#ifndef C4H
#define C4H
void StrPrint(HString T);
#endif
------------------------------------------------------------------------------------------
bo4-2.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
//函数及结构体申明在c4-2.h中
--------------------------------------------------------------------------------
c4-3.h
#ifndef ALGO43H
#define ALGO43H
#include "c2-5.h"
#include "c4-2.h"
typedef int ElemType;
//bo2-6.cpp function
void MakeNode(Link &p,ElemType e);
void FreeNode(Link &p);
void InitList(LinkList &L);
void ClearList(LinkList &L);
void DestroyList(LinkList &L);
void InsFirst(LinkList &L,Link h,Link s); // 形参增加L,因为需修改L
Status DelFirst(LinkList &L,Link h,Link &q); // 形参增加L,因为需修改L
void Append(LinkList &L,Link s);
Position PriorPos(LinkList L,Link p);
Status Remove(LinkList &L,Link &q);
void InsBefore(LinkList &L,Link &p,Link s);
void InsAfter(LinkList &L,Link &p,Link s);
void SetCurElem(Link p,ElemType e);
ElemType GetCurElem(Link p);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Position GetLast(LinkList L);
Position GetHead(LinkList L);
Position NextPos(Link p);
Status LocatePos(LinkList L,int i,Link &p);
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType));
void ListTraverse(LinkList L,void(*visit)(ElemType));
void OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType));
Status LocateElem(LinkList L,ElemType e,Position &q,int(*compare)(ElemType,ElemType));
//algo4-3.cpp
#define MaxKeyNum 25 //索引表的最大容量(关键词的最大数目)
#define MaxLineLen 52
#define MaxNoIdx 10
struct WordLisType//一个书目的词表(顺序表)和非索引词表(有序表)共用类型
{
};
struct IdxTermType
{
};
struct IdxListType
{
};
void InitIdxList(IdxListType &idxlist);
void ExtractKeyWord(int &BookNo);
void GetWord(int i, HString &wd);
int Locate(IdxListType &idxlist, HString wd, Status &b);
void InsertNewKey(IdxListType &idxlist,int i,HString wd);
void InsertBook(IdxListType &idxlist, int i, int bno);
void InsIdxList(IdxListType &idxlist , int bno);
void PutText(FILE *f , IdxListType idxlist);
void algo43_main(void);
//algo4-4.cpp
#define MaxBookNum 10 // 假设只对10个书名建索引表
#define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
struct BookTermType // 书目项类型
{
};
struct BookListType // 书目表类型(有序表)
{
void algo44_main();
#endif
---------------------------------------------------------------------------------
algo4-3.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
//函数及结构体申明在algo4-3.h中
//全局变量
BK
char buf[MaxLineLen+1];
WordLisType wdlist,noidx;
//初始化操作,置索引表idxlist为空表,且在idxlist.item[0]设一空串
void InitIdxList(IdxListType &idxlist)
{
}
void ExtractKeyWord(int &BookNo)
{
}
//用wd返回词表wdlist中的第i个关键词
void GetWord(int i, HString &wd)
{
}
//在索引表idxlist中查询是否存在与wd相等的关键词。若存在,则返回其在索引表中的位置,且b取值TRUE;否则返回插入的位置,且b取值FALSE
int Locate(IdxListType &idxlist, HString wd, Status &b)
{
}
//索引表idxlist的第i项上插入关键词wd,并初始化书号索引的链表为空表
void InsertNewKey(IdxListType &idxlist,int i,HString wd)
{
}
//在索引表idxlist的第i项中插入书号为bno的索引
void InsertBook(IdxListType &idxlist, int i, int bno)
{
}
//将新书号为bno的关键词插入索引表
void InsIdxList(IdxListType &idxlist , int bno)
{
}
//将生成的索引表idxlist输出到文件f
void PutText(FILE *f , IdxListType idxlist)
{
}
void algo43_main(void)
{
}
---------------------------------------------------------------------------------
algo4-3.h
#ifndef ALGO43H
#define ALGO43H
#include "c2-5.h"
#include "c4-2.h"
typedef int ElemType;
//bo2-6.cpp function
void MakeNode(Link &p,ElemType e);
void FreeNode(Link &p);
void InitList(LinkList &L);
void ClearList(LinkList &L);
void DestroyList(LinkList &L);
void InsFirst(LinkList &L,Link h,Link s); // 形参增加L,因为需修改L
Status DelFirst(LinkList &L,Link h,Link &q); // 形参增加L,因为需修改L
void Append(LinkList &L,Link s);
Position PriorPos(LinkList L,Link p);
Status Remove(LinkList &L,Link &q);
void InsBefore(LinkList &L,Link &p,Link s);
void InsAfter(LinkList &L,Link &p,Link s);
void SetCurElem(Link p,ElemType e);
ElemType GetCurElem(Link p);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Position GetLast(LinkList L);
Position GetHead(LinkList L);
Position NextPos(Link p);
Status LocatePos(LinkList L,int i,Link &p);
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType));
void ListTraverse(LinkList L,void(*visit)(ElemType));
void OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType));
Status LocateElem(LinkList L,ElemType e,Position &q,int(*compare)(ElemType,ElemType));
//algo4-3.cpp
#define MaxKeyNum 25 //索引表的最大容量(关键词的最大数目)
#define MaxLineLen 52
#define MaxNoIdx 10
struct WordLisType//一个书目的词表(顺序表)和非索引词表(有序表)共用类型
{
};
struct IdxTermType
{
};
struct IdxListType
{
};
void InitIdxList(IdxListType &idxlist);
void ExtractKeyWord(int &BookNo);
void GetWord(int i, HString &wd);
int Locate(IdxListType &idxlist, HString wd, Status &b);
void InsertNewKey(IdxListType &idxlist,int i,HString wd);
void InsertBook(IdxListType &idxlist, int i, int bno);
void InsIdxList(IdxListType &idxlist , int bno);
void PutText(FILE *f , IdxListType idxlist);
void algo43_main(void);
//algo4-4.cpp
#define MaxBookNum 10 // 假设只对10个书名建索引表
#define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
struct BookTermType // 书目项类型
{
};
struct BookListType // 书目表类型(有序表)
{
void algo44_main();
#endif
---------------------------------------------------------------------------------
algo4-4.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
#include "first.h"
//结构体定义和函数声明放在algo4-3.h中
//调整algo44_main()函数的一些地方以适应book.txt文件数据的存放模式
---------------------------------------------------------------------------------
bo2-6.cpp
#include "c1.h"
typedef int ElemType;
#include "c2-5.h"
#include "c4-2.h"
#include "algo4-3.h"
// bo2-6.cpp 具有实用意义的线性链表(存储结构由c2-5.h定义)的24个基本操作
//函数及结构体申明在algo4-3.h中
---------------------------------------------------------------------------------
c1.h
#ifndef HEAD1
#define HEAD1
#include
#include
#include
#include
#include
#include
#include
#include
#include //exit()
#include //cout,cin
//函数结果状态代码
#define TRUE
#define FALSE
#define OK
#define ERROR
#define INFEASIBLE -1
//#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status;
typedef int Boolean;
#endif
---------------------------------------------------------------------------------
c2-5.h
#ifndef C2H
#define C2H
typedef int ElemType;
#endif
---------------------------------------------------------------------------------------------