/*
图书登记管理程序
*/
#include<stdio.h>
#include<stdlib.h>
//定义一个图书结构体
typedef struct aBook{
char ISBN[25];//国际标准书号(ISBN)
char name[25];//图书名称
char publishHouse[20];//图书出版社
char author[20];//图书作者
float price;//图书价格,并初始化
char publishDate[20];//出版日期
int amount ;//图书数量
struct BOOK *pNext;
}BOOK;//结构体别名
BOOK head;//头结点,全局变量
void displayMenu();// 显示菜单
void doMenu();//处理菜单
void addNewBook();// 从键盘输入添加新图书
void addBookFromFile();// 从文件中添加新图书
void displayAllBooks();// 显示书库所有图书信息
void saveBookToFile();// 保存所有图书信息到文件
void knowAuthorFindBook();// 根据作者,查找图书
void know_ISBN_FindBook();// 根据ISBN,查找图书
void know_ISBN_MotifyBook();// 根据ISBN,修改图书
void know_ISBN_DeleteBook();// 根据ISBN,删除图书
void displayBookAllCount ();
//程序入口 //=========main======main==========main===========main========main==========main
int main(){
head.pNext=NULL;
while(1){
system(" mode con cols=130 lines=45 "); //cols为控制台的宽度,lines则代表控制台的高度。
displayMenu();
doMenu();}
return 0;
}
//=========main======main==========main===========main========main==========main===========main
// 显示菜单
void displayMenu(){
printf("\t\t \t\t \n");
printf("\t\t*****************************************\n");
printf("\t\t* \t\t\n");
printf("\t\t* 图书登记管理系统 \t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t1-从键盘输入添加新图书\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t2-从文件中添加新图书\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t3-保存所有图书信息到文件\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t4-显示书库所有图书信息\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t5-根据作者,查找图书\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t6-根据ISBN,查找图书\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t7-根据ISBN,修改图书\t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*\t\t8-根据ISBN,删除图书\t\t\n");
printf("\t\t*\t\t \t\t\n");
printf("\t\t*\t\t9-查看图书总数量\t\t\n");
printf("\t\t*\t\t \t\t\n");
printf("\t\t*\t\t0---退出--- \t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t* \t\t\n");
printf("\t\t*****************************************\n");
}
void doMenu(){
int choice;
printf("请输入数字进行选择\n");
scanf("%d",&choice);
switch(choice){
case 1:
system("cls");
addNewBook();
system("cls");
displayMenu();
doMenu();
break;
case 2:
system("cls");
addBookFromFile();
system("cls");
displayMenu();
doMenu();
break;
case 3:
system("cls");
saveBookToFile();
system("cls");
displayMenu();
doMenu();
break;
case 4:
system("cls");
displayAllBooks();
system("pause");
system("cls");
displayMenu();
doMenu();
break;
case 5:
system("cls");
knowAuthorFindBook();// 根据作者,查找图书
system("pause");
system("cls");
displayMenu();
doMenu();
break;
case 6:
system("cls");
know_ISBN_FindBook();// 根据ISBN,查找图书
system("pause");
system("cls");
displayMenu();
doMenu();
break;
case 7:
system("cls");
know_ISBN_MotifyBook();
system("pause");
system("cls");
displayMenu();
doMenu();
break;
case 8:
system("cls");
know_ISBN_DeleteBook();
system("cls");
displayMenu();
doMenu();
break;
case 9:
system("cls");
displayBookAllCount ();
system("cls");
displayMenu();
doMenu();
case 0:
exit(0);
break;
}
}
//创建&链表添加图书
void addNewBook(){
printf("\t\t \t\t\n");
printf("|-------------------------请输入图书的以下内容(以空格分开),以下一本图书的ISBN为0结束添加图书---------------------------------|\n");
printf("\t\t \t\t\n");
printf("|-ISBN(13位数字)-|----------名称-----------|--------出版社----------|----作者----|--价格--|出版日期用-分隔|--数量(本)--|\n");
BOOK* pTail=NULL;
if(head.pNext==NULL)//如果头结点的指针等于空
pTail=&head;//尾指针指向头结点
else
pTail=head.pNext ;//否则即 已经存在有图书数据, 尾指针指向最后一个结点 ,最后一个结点的特点是指针域为空
while(pTail->pNext !=NULL) {// 已经存在有图书数据, 尾指针要实现找到最后一个结点
pTail=pTail->pNext ;}//往下找,直到找到最后一个结点为止 ,
char end='1';
while(1){
BOOK* pNewNode=(BOOK*)malloc(sizeof(BOOK));//申请空间专用指针
if(pNewNode==NULL)//申请失败则malloc会返回空
printf("图书添加功能发生了错误,请联系技术人员!\n");
pNewNode->pNext = NULL;//把新结点指针域赋值为空
scanf("%s",pNewNode->ISBN);//读取图书ISBN
end=pNewNode->ISBN[0];//判断用户是否结束输入
if(end=='0') {//是则退出循环
free(pNewNode);//释放指针
break;}//.......控制while循环,退出循环
scanf("%s %s %s %f %s %d",pNewNode->name,pNewNode->publishHouse,
pNewNode->author,&pNewNode->price,pNewNode->publishDate,&pNewNode->amount);
//读取图书信息
pTail->pNext = pNewNode;//已经有数据的新结点存放在上一个结点的指针域
pTail=pNewNode; } //尾指针指向最后一个结点pNewNode
if(head.pNext==NULL)
printf("没有添加图书\n正在返回主菜单\n");//进来但没加图书的的情况
else
printf("以上图书添加成功!\n");//以上一本或多本图书成功添加
return;
}
//显示所有图书
void displayAllBooks(){
BOOK* printAll=head.pNext ;//指向头结点的指针域(存放第一个数据域的地方)
if(printAll==NULL){
printf("还没有图书,快去添加图书吧\n");
return ;}
printf("所有的图书:\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
while(printAll!=NULL){
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
printAll->ISBN,printAll->name,printAll->publishHouse ,
printAll->author ,printAll->price ,printAll->publishDate ,printAll->amount );
printAll=printAll->pNext ;
printf("|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
}
}
// 根据作者,查找图书
void knowAuthorFindBook(){
BOOK* pFind=head.pNext;//指向头结点的指针域(存放第一个数据域的地方)
printf("请输入图书作者的名字,以进行查找\n");
char name[20];//建立数组存放用户的输入
scanf("%s",name);
while(pFind!=NULL){
if(strcmp(pFind->author,name)==0){
printf("找到了该书\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
pFind->ISBN,pFind->name,pFind->publishHouse ,
pFind->author ,pFind->price ,pFind->publishDate ,pFind->amount );
printf("|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
system("pause");
break;
}
pFind=pFind->pNext; //往下找
}
if(pFind==NULL)
printf("没有");
}
// 根据ISBN,查找图书
void know_ISBN_FindBook(){
BOOK* pFind=head.pNext;//指向头结点的指针域(存放第一个数据域的地方)
printf("请输入图书的ISBN,以进行查找\n");
char ISBN[20];
scanf("%s",ISBN);
while(pFind!=NULL){
if(strcmp(pFind->ISBN,ISBN)==0){//存在相同,找到...
printf("找到了该书\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
pFind->ISBN,pFind->name,pFind->publishHouse ,
pFind->author ,pFind->price ,pFind->publishDate ,pFind->amount );
printf("|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
system("pause");
break;}
pFind=pFind->pNext; } //往下找
if(pFind==NULL)
printf("没有该图书存在\n");
}
// 根据ISBN,修改图书
void know_ISBN_MotifyBook(){
BOOK* pFind=head.pNext;//指向头结点的指针域(存放第一个数据域的地方)
printf("请输入图书的ISBN,以进行修改\n");
char ISBN[20];
scanf("%s",ISBN);
while(pFind!=NULL){
if(strcmp(pFind->ISBN,ISBN)==0){ //存在相同则找到
printf("存在该书\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
pFind->ISBN,pFind->name,pFind->publishHouse ,
pFind->author ,pFind->price ,pFind->publishDate ,pFind->amount );
printf("|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
printf("请输入修改后的数据\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
scanf("%s",pFind->ISBN);//读取并覆盖数据以达到修改的目的
scanf("%s %s %s %f %s %d",pFind->name,pFind->publishHouse,
pFind->author,&pFind->price,pFind->publishDate,&pFind->amount);
printf("修改成功,如下\n");//输出修改后的数据结用户核对一下
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
pFind->ISBN,pFind->name,pFind->publishHouse ,
pFind->author ,pFind->price ,pFind->publishDate ,pFind->amount );
system("pause");
break; }
pFind=pFind->pNext;} //往下找
if(pFind==NULL)
printf("没有该书,修改失败!");
}
// 根据ISBN,删除图书
void know_ISBN_DeleteBook(){
BOOK* previous=&head ;//待删除的数据存放在前一个结点,指向待删除的前一个节点
BOOK* pRemove=head.pNext ; //指向待删除的结点
char sel;
printf("请输入图书的ISBN,以删除该书!\n");
char ISBN[20];
scanf("%s",ISBN);
while(pRemove!=NULL) {
if(strcmp(pRemove->ISBN ,ISBN)==0){//找到了
printf("找到这本书\n");
printf("|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
printf("| %-14s | %-23s | %-22s | %-10s | %-6.2f | %-13s | %-10d |\n",
pRemove->ISBN,pRemove->name,pRemove->publishHouse ,
pRemove->author ,pRemove->price ,pRemove->publishDate ,pRemove->amount );
printf("|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
fflush(stdin);//清除缓冲区,以免影响下一步的输入
printf("是否确定删除该图书?!\n输入Y确定,输入其他按键取消删除!\n");
sel=getchar( );
if(sel=='Y'||sel=='y') {
previous->pNext = pRemove->pNext ;//断链操作
printf("删除成功!\n");
return ;
}
else{
printf("取消删除成功!\n");
system("pause");
return ;}
}
previous=previous->pNext ;//往下找
pRemove=pRemove->pNext ;//往下找
printf("正在查找.....请稍候.......\n");
}
printf("没有找到该书,删除失败!!!");
return ;
}
// 保存所有图书信息到文件
void saveBookToFile(){
FILE *fp;//定义一个文件指针
if(head.pNext==NULL){//当头结点的指针域没有存放数据
printf("书库没有图书,无法保存\n");
system("pause");
return ;
}
if((fp=fopen("图书.txt","w"))==NULL){ //自动创建一个文件并写入数据 ,等于空即无法创建文件时,提示用户
printf("未知错误,无法保存\n");
return ;
}
BOOK* pWrite=head.pNext;//
//fprintf(fp,"|------ISBN------|----------名称-----------|--------出版社----------|----作者----|--价格--|----出版日期---|--数量(本)--|\n");
while(pWrite!=NULL){
fprintf(fp," %-14s %-23s %-22s %-10s %-6.2f %-13s %-10d \n",
pWrite->ISBN,pWrite->name,pWrite->publishHouse ,
pWrite->author ,pWrite->price ,pWrite->publishDate ,pWrite->amount );
// fprintf(fp,"|----------------|-------------------------|------------------------|------------|--------|---------------|------------|\n");
pWrite=pWrite->pNext;
printf("数据保存中......\n");
}
fclose(fp);
printf("数据保存成功..!\n");
system("pause");
return;
}
//从文件中添加图书
void addBookFromFile() {
int n;
//删除链表的数据 //定义了两个指针,一个是用来作副本,一个进行相关操作
BOOK* pTail,*pCloseToHead;//pTail指针先是从头开始找最终最指向最后一个结点命名为pTail, 而第二个指针始终指向头结点的指针域(存放第一个数据域的地方)
pTail=pCloseToHead=head.pNext ;
while(pCloseToHead!=NULL) {//有数据存在时
pTail=pTail->pNext ;//尾巴从前面的头往下移
free(pCloseToHead);//释放了指针
pCloseToHead=pTail; //尾巴赋值结pCloseToHead指针, pCloseToHead指针指向了尾指针
}
head.pNext = NULL;//删除完原来的数据后,不妨把头的指针域为空,方便下面的语句进行判断
FILE *fp;
if((fp=fopen("图书.txt","r"))==NULL){ //没有这文件时无法打开
printf("文件不存在或无法打开!\n");
return;
}
while(!feof(fp)){
//创建结点 1
BOOK* pNewNode=(BOOK*)malloc(sizeof(BOOK));//申请空间专用指针,先申请一个空间
pNewNode->pNext =NULL;
//从文件读取数据 把数据存入到新结点
n=fscanf(fp,"%s %s %s %s %f %s %d",pNewNode->ISBN,pNewNode->name,pNewNode->publishHouse,
pNewNode->author,&pNewNode->price,pNewNode->publishDate,&pNewNode->amount);
if(n<1)break;
if(head.pNext == NULL){ //如果头的指针域为空,则为这个链表没有数据
head.pNext = pNewNode; //把刚刚已经存放到新结点的结点给头结点的指针域用来存放到链表中
pTail=head.pNext;}//尾指针指向头的数据域
else{//如果链表已经有数据存在的情况下
pTail->pNext = pNewNode;//上面的新结点挂在尾指针的指针域用来存放新数据
pTail=pTail->pNext ;//因为多了一个刚才新加的结点,目前尾结点指的不是最后一个指点,则现在让尾指针移动到最后一个结点
pTail->pNext = NULL; //最后一个结点的指针域赋值为空
}
printf("数据读取中......!\n"); //提示用户,数据正在读取中
}
fclose(fp) ;
printf("读取成功!\n");
printf("图书添加成功!\n");
/* 关闭文件 */
system("pause");
}
void displayBookAllCount (){
BOOK* pFind=head.pNext;//指向头结点的指针域(存放第一个数据域的地方)
int sumBooks=0;
while(pFind!=NULL){
sumBooks+=pFind->amount;
pFind=pFind->pNext; //往下找
}
displayAllBooks();
printf("|*****************************************************************************************| 所有的图书总数为 %d 本图书 \n",sumBooks);
system("pause");
}
运行效果