⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bookindex.cpp

📁 图书馆书目属引表,是一个很好的图书查询工具.
💻 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 + -