📄 bookindex.cpp
字号:
// 使用说明
//输入文件必须存在且包含后缀名,不支持中文
//书目信息文件的每行包括书号和书名格式如下
//1001 chunqiu lishi
//1002 jisuanji wenhua
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
#include<fstream.h>
/////////////////////
const KEYWORDCOUNT=21;//关键词的最多数量值
const KEYWORDLENGTH=20;//关键词的最大长度值
const BOOKINFLENGTH=110;//书目信息串的最大长度值
const BOOKNAMELENGTH=100;//书名的最大长度值
const BOOKNUMBERLENGTH=4;//书号的最大长度值
///////////////define book number list node class and number list class////////////
class NumberListNode
{
public:
char *booknumber;
NumberListNode *next;
NumberListNode(){next=NULL;booknumber=NULL;}
NumberListNode(char *bnumber)
{
next=NULL;
booknumber=new char[BOOKNUMBERLENGTH];
strcpy(booknumber,bnumber);
}
};
class NumberList
{
public:
int length;
NumberListNode *head,*rear;
NumberList(){length=0;head=rear=new NumberListNode();}
NumberList(char *bnumber){head=rear=new NumberListNode(bnumber);}
void AddRear(char *bnumber); //向链表表尾填加书号函数
void ShowNumberList(); //显示书号链表函数
void SaveNumberList(ofstream outfile);//保存书号链表函数
};
void NumberList::AddRear(char *bnumber)
{
try
{
NumberListNode *newNode=new NumberListNode(bnumber);
rear->next=newNode;
rear=newNode;
length++;
}
catch(...){ cout<<"AddNumber Error!"<<endl; }
}
void NumberList::ShowNumberList()
{
NumberListNode *show=head->next;
while(show)
{
cout<<setw(6)<<show->booknumber;
show=show->next;
}
cout<<endl;
}
void NumberList::SaveNumberList(ofstream outfile)
{
NumberListNode *save=head->next;
while(save)
{
outfile<<setw(6)<<save->booknumber;
save=save->next;
}
outfile<<endl;
}
///////////////define book index list node class and book list class//////////////
class BookIndexListNode
{
public:
char *keyword; //关键词指针,以堆式存储结构存储关键词,根据关键词长度建立堆的大小
NumberList *numberlist; //存放书号的链表对象指针
BookIndexListNode *next; //指向索引链表下一个节点的指针
BookIndexListNode() //构造函数一,用于建立表头节点,头节点空置,为操作方便
{
next=NULL;
keyword=NULL;
numberlist=new NumberList();
}
BookIndexListNode(char *bnumber)//构造函数二,用于建立中间节点,利用参数给节点赋值
{
next=NULL;
keyword=NULL;
numberlist=new NumberList(bnumber);
}
};
class BookIndexList
{
public:
BookIndexList(){currPtr=head=rear=new BookIndexListNode();wordcount=listlength=0;}//构造函数
void AddBookIndexBook(char *bookname,char *booknumber);//填加函数//
void FindBookKeyWord(); //查找函数
void SaveBookIndexList(); //保存文件函数
void ShowBookIndexList(); //显示索引表函数
void ClearBookIndexList();
bool CheckListIsEmpty(){if(!listlength)return true;return false;}
protected:
void AnlysKeyWord(char *bookname); //分析书目信息,提取关键词函数
//将书目中的关键词存放于k_word[]中
bool CheckKeyWord(char *kword); //在索引表中查找关键词函数,以字母顺序查找
//找到匹配的关键词,将currptr指向该节点
//并返回true,否则按字母顺序找到该关键词的前趋节点
//并将currptr指向该前趋节点,返回false
void AddBookIndexListNode(char *bname,char *bnumber);//填加链表节点函数
private:
int wordcount,listlength; //存放一本书的关键词的个数的变量
char *k_word[KEYWORDCOUNT]; //暂存书目关键词的字符串数组
BookIndexListNode *currPtr; //用于指向当前要操作的节点的指针变量
BookIndexListNode *head,*rear; //链表表头和表尾指针
};
void BookIndexList::AddBookIndexBook(char *bookname,char *booknumber)
{
AnlysKeyWord(bookname);
for(int i=1;i<=wordcount;i++)
{
if(CheckKeyWord(k_word[i]))//找到相匹配的关键词,就将书号填加到该节点的书号链表中
{
currPtr->numberlist->AddRear(booknumber);
}
else//找不到相匹配的关键词,在该关键词的前趋节点和后趋节点之间插入一个新的节点
{
AddBookIndexListNode(k_word[i],booknumber);
}
}
}
void BookIndexList::AnlysKeyWord(char *bookname)
{
//提取关键词,该操作,在书名的尾部加上一标志符 '\n'
//以空格为关键的分界符,将关键词存放于k_word[]中
//遇到标志符时分析结束
wordcount=0;
int chnumber=0;
int number=0;
bool check=false;
char kword[KEYWORDLENGTH];
for(int j=0;j<=KEYWORDLENGTH;j++){kword[j]='\0';}
int count=strlen(bookname);
*(bookname+count)='\n';
for(int i=0;i<=count;i++)
{
if(*(bookname+i)!=' ')
{
if(*(bookname+i)=='\n' && chnumber!=0)
{
wordcount++;
try{k_word[wordcount]=new char [chnumber];}
catch(...){cout<<"Memory Error!"<<endl;return;}
strcpy(k_word[wordcount],kword);
for(int j=0;j<KEYWORDLENGTH;j++){kword[j]='\0';}
return;
}
else
{
kword[chnumber]=*(bookname+i);
chnumber++;
check=true;
}
}
else
{
if(check)
{
wordcount++;
try{k_word[wordcount]=new char [chnumber];}
catch(...){cout<<"Memory Error!"<<endl;return;}
strcpy(k_word[wordcount],kword);
for(int j=0;j<KEYWORDLENGTH;j++){kword[j]='\0';}
}
chnumber=0;
check=false;
}
}
}
bool BookIndexList::CheckKeyWord(char *kword)
{
//add check keyword code
BookIndexListNode *find=head->next;
currPtr=head;//指向第一个节点的前驱节点
while(find)
{
if(strcmp(find->keyword,kword)==0)
{
currPtr=find;//匹配时,只指向当前节点,以便填加书号操作
return true;
}
else if(strcmp(find->keyword,kword)>0){return false;}
else
{
currPtr=find;//指向要查找节点的前驱节点
find=find->next;//指向下一节点
}
}
return false;
}
void BookIndexList::AddBookIndexListNode(char *kword,char *bnumber)
{
//add node bookname
BookIndexListNode *pNode;
BookIndexListNode *newNode;
try{
newNode=new BookIndexListNode(bnumber);
newNode->keyword=new char;
}
catch(...){cout<<"Memory Error!"<<endl;return;}
strcpy(newNode->keyword,kword);
newNode->numberlist->AddRear(bnumber);
pNode=currPtr->next;
currPtr->next=newNode;
newNode->next=pNode;
currPtr=newNode;
listlength++;
}
void BookIndexList::FindBookKeyWord()
{
char bookkeyword[BOOKNAMELENGTH];
cout<<"输入关键词,多关键词用空格隔开\n>";
//从键盘接收字符串,关键词与空格的总长度不超过书名长度
cin.getline(bookkeyword,BOOKNAMELENGTH);
cin.getline(bookkeyword,BOOKNAMELENGTH);
AnlysKeyWord(bookkeyword);//分析书名,提取关键词,存入 k_word[] 中
cout<<"索引表"<<endl<<endl;
cout<<"关键字"<<setw(KEYWORDLENGTH)<<"书号索引"<<endl;
for(int i=1;i<=wordcount;i++)
{
if(CheckKeyWord(k_word[i]))
{ //查找关键词,找到显示有关信息,否则显示提示信息
cout<<setiosflags(ios::left)
<<setw(KEYWORDLENGTH)
<<currPtr->keyword;
currPtr->numberlist->ShowNumberList();
}
else
{
cout<<"※ 没有您想要的书目 ※"<<endl;
}
}
}
void BookIndexList::SaveBookIndexList()
{
//保存索引文件,文件名为 bookkeywordindex.txt
BookIndexListNode *save=head->next;
ofstream bookfile("bookkeywordindex.txt",ios::out);
while(save)
{
bookfile<<setiosflags(ios::left)
<<setw(KEYWORDLENGTH)
<<save->keyword;
save->numberlist->SaveNumberList(bookfile);
save=save->next;
}
bookfile.close();
cout<<"文件保存成功!"<<endl;
}
void BookIndexList::ShowBookIndexList()
{
//显示索引链表信息
cout<<"索引表"<<endl<<endl;
cout<<"关键字"<<setw(KEYWORDLENGTH)<<"书号索引"<<endl;
BookIndexListNode *show=head->next;
if(!show){cout<<"还未建立索引表"<<endl;}
while(show)
{
cout<<setiosflags(ios::left)
<<setw(KEYWORDLENGTH)
<<show->keyword;
show->numberlist->ShowNumberList();
show=show->next;
}
cout<<endl;
}
void BookIndexList::ClearBookIndexList()
{
BookIndexListNode *nextnode=head->next;
BookIndexListNode *delnode;
while(nextnode)
{
delnode=nextnode;
nextnode=nextnode->next;
delete delnode;
}
listlength=0;
head->next=NULL;
cout<<"索引表为空"<<endl;
}
/////////////////define data ///////////////////////////////////////
BookIndexList bookindexlist; //定义索引链表对象
char bookinf[BOOKINFLENGTH]; //定义书目信息串字符数组
char key_word[BOOKNAMELENGTH]; //定义关键词字符数组
char book_name[BOOKNAMELENGTH]; //定义书名字符数组
char booknumber[BOOKNUMBERLENGTH]; //定义书号字符数组
/////////////////defind subfunction/////////////////////////////////
void InsertBookItem()
{
int bookcount,n;
char booknumber[BOOKNUMBERLENGTH];
char bookname[BOOKNAMELENGTH];
for(n=0;n<BOOKNUMBERLENGTH;n++){booknumber[n]='\0';}//初始化数组//
for(n=0;n<BOOKNAMELENGTH;n++){bookname[n]='\0';}//初始化数组//
ofstream addbook("bookinf.txt",ios::out|ios::app);
cout<<"插入书的数量:";
cin>>bookcount;
for(int i=1;i<=bookcount;i++)
{
cout<<"请输入书名:";
cin.getline(bookname,BOOKNAMELENGTH);
cin.getline(bookname,BOOKNAMELENGTH);
cout<<"请输入书号:"; cin>>booknumber;
cout<<endl;
bookindexlist.AddBookIndexBook(bookname,booknumber);
addbook<<booknumber<<' '<<bookname;
}
addbook.close();
}
void OpenBookFile()
{
char check;
if(!bookindexlist.CheckListIsEmpty())
{
cout<<"要关闭当前文件吗?[按 Y|y 确定 其他键 取消]"<<endl;
cin>>check;
if(check=='Y'||check=='y'){ bookindexlist.ClearBookIndexList();}
else return;
}
int length,count,n;
char file_name[100],*p=NULL;
cout<<"请输入文件名:";
cin>>file_name;
ifstream book(file_name,ios::in); //建立输入流对象
while(!book.eof())
{
for(n=0;n<BOOKINFLENGTH;n++){bookinf[n]='\0';} //清空字符数组//
book.getline(bookinf,BOOKINFLENGTH); //读入书目信息//
strncpy(booknumber,bookinf,BOOKNUMBERLENGTH); //复制书号//
length=strlen(bookinf); //获取书目信息字符串长度//
count=length-BOOKNUMBERLENGTH-1; //获取书名字符串长度//
p=bookinf+BOOKNUMBERLENGTH+1; //获取书名字符串初始地址//
for(n=0;n<BOOKNAMELENGTH;n++){book_name[n]='\0';} //清空字符数组//
strncpy(book_name,p,count); //复制书名//
bookindexlist.AddBookIndexBook(book_name,booknumber); //向关键词索引表填加书目
}
cout<<"※ 索引建立成功 ※"<<endl;
book.close();
}
//显示书目信息文件函数
void ShowBookList()
{
//读取书目信息文件显示于屏幕
char bookinformation[BOOKINFLENGTH];
ifstream in("bookinf.txt",ios::in);
cout<<"书号"<<setw(KEYWORDLENGTH)<<"书名"<<endl;
while(!in.eof())
{
in.getline(bookinformation,BOOKINFLENGTH);
cout<<bookinformation<<endl;
}
cout<<endl;
in.close();
}
/////////////////define main function///////////////////////////////
void main()
{
int option;
cout<<" ※书目索引※"<<endl<<endl;
cout<<" 使用说明 "<<endl;
cout<<"输入文件必须存在且包含后缀名,不支持中文"<<endl;
cout<<"书目信息文件的每行包括书号和书名格式如下"<<endl;
cout<<"1001 chunqiu lishi "<<endl;
cout<<"1002 jisuanji wenhua "<<endl;
cout<<"※书目索引※"<<endl<<endl;
cout<<"1........建立索引"<<endl;
cout<<"2........书目查询"<<endl;
cout<<"3........插入书目"<<endl;
cout<<"4........显示索引"<<endl;
cout<<"5........显示书目"<<endl;
cout<<"6........保存文件"<<endl;
cout<<"0........结束程序"<<endl;
cout<<'>';
cin>>option;
switch(option)
{
case 1: OpenBookFile(); break;
case 2: bookindexlist.FindBookKeyWord(); break;
case 3: InsertBookItem(); break;
case 4: bookindexlist.ShowBookIndexList(); break;
case 5: ShowBookList(); break;
case 6: bookindexlist.SaveBookIndexList(); break;
default:cout<<"Thanks For Using The Soft!"<<endl;return;
}
main();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -