图书登记管理程序
问题描述:
请设计一个图书登记管理程序,以方便图书管理员管理图书馆内的图书,该程序应该具有以下功能:
(1)从键盘输入某本图书的信息
(2)给定书号(ISBN),显示该图书的信息。
(3)给定图书的作者,显示所有该作者所著的图书。
(4)给定书号(ISBN),修改该图书的信息。
(5)给定书号(ISBN),删除该图书的信息。
题目要求:
(1)按照分析、设计、编码、调试、测试的软件过程完成这个应用程序。
(2)图书信息应该包含 书号、图书名称、图书出版社、图书作者(假设一个作者)、图书价格、出版时间。
(3)为各项操作功能设计一个菜单,应用程序运行后,先显示这个菜单,然后用户通过菜单项选择希望进行的操作项目。
输入要求:
(1)应用程序运行后在屏幕上显示一个菜单。用户可以根据需求,选定相应的操作项目。进入每个操作后,根据应用程序的提示信息,从键盘输入相应的信息。程序根据用户输入的信息完成相应的处理,实现要求的功能。
(2)能对输入的数据进行简单的校验,例如,出版时间必须是一个合法的日期格式,国际标准书号是唯一的(一个国际标准书号对应一种图书信息)。
输出要求:
(1)应用程序运行后,要在屏幕上显示一个菜单。
(2)要求用户输入数据时,给出清晰、明确的提示信息,包括输入的数据内容、格式以及结束方式等。
(3)在程序完成处理后,要清楚地给出程序的处理结果。例如,在给定国际标准书号删除图书信息时,如果该图书不存在,要提示没能删除,如果删除成功要提示删除成功。
实现要求:
(1)在程序中使用链表存储图书信息。
(2)采用模块化程序设计的方法,将程序中的各项功能用函数实现。
提示:
(1)使用结构体表示图书信息,一个结点保存一条图书信息。
扩展功能:
(1)提供一些统计功能。例如统计每个出版社的图书种类数,统计每个作者的图书种类数。
(2)图书信息从文件读入。
(3)将图书信息保存到文件中。
系统主要包括功能:
- 显示功能界面
- 添加书本信息
- 查看指定书本信息
- 修改指定书本的信息
- 删除指定书本的信息
- 统计按(出版社)分类计数
- 统计按(作者)分类计数
- 从文件读入信息
- 将信息输出到文件
程序测试与结果
1. 添加书本信息
1) 正常输入时
2) 多次输入错误时,自动退出
3) 输入ISBN号不唯一,提示有误
4) 输入的日期有误时,提示重新输入
2. 查看书本信息(通过ISBN号指定)
1) 正常情况
2) 当程序中还未保存信息时,提示暂未存储数据
3) 当输入的ISBN号不存在时,提示没有找到
3. 查看指定作者的所有书本信息
1) 正常情况
2) 输入的作者名不存在时,提示找不到
4. 修改指定书本信息
1) 正常情况
2) 当输入指定的ISBN号有误时,提示找不到书本
3) 当输入更新的ISBN号有误时,重新输入;多次输入有误时,不更新数据,重新选择
4) 当输入更新的日期有误是,重新输入;多次输入有误时,不更新数据,重新选择(此图片未更新,以代码运行效果为准)
5. 删除指定书本信息
1) 正常情况
2) 输入的ISBN号不存在时,提示找不到
3) 当程序中还未保存信息时,提示暂未存储数据
6. 按出版社分类,统计书的数量
1) 正常情况
2) 当程序中还未保存信息时,提示暂未存储数据
7. 按作者分类,统计书的数量
1) 正常情况
2) 当程序中还未保存信息时,提示暂未存储数据
8. 从指定文件中读取数据
1) 正常情况
2) 当输入的路径有误时,提示读取文件失败
3) 当指定的文件中读取的数据有错误时,提示已添加的数据量及碰见的错误
9. 将数据写入指定文件中
1) 正常情况
2) 输入的文件不存在时,会新建文件
源代码(可直接运行)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
typedef struct books
{
char isbn[18];
char name[20];
char author[9];
char publisher[30];
float price;
char date[9]; // 时间格式20201212
struct books *nextBooks;
} BOOKS, *PBOOKS;
/**
* 声明所需函数:
* 1 界面
* 2 创建一个链表,初始化头结点
* 3 添加信息 函数,生成一个结点,写入信息
* 4 修改信息 函数,遍历链表,找到指定条件,修改结点中信息
* 5 删除信息 函数,遍历链表,判断指定条件,删除结点
* 扩展:
* 6 统计 按(出版社)分类-->计数,创一个链表保存出版社的名称与书的数量,遍历输出
* 7 统计 按(作者)分类-->计数,创一个链表保存作者的名称与书的数量,遍历输出
* 8 从文件读入信息
* 9 将信息 输出 到文件
*
* */
// 前置声明
void Interface(); // 显示界面
void createLinked(); // 初始化链表
void add(); // 添加书的信息
void findIsbn(); // 通过isbn查找书的信息
int isbnEqual(char *, char *, int); // 判断两个isbn号是不是相等,参数3为长度,可以用作其它判断
void findName(); // 通过作者名查找其所有书的信息
void isbnUpdate(); // 通过isbn号修改指定书的信息
void isbnDelete(); // 通过isbn号删除指定书的信息
void inputFile(); // 通过文件读入书的记录
void outputFile(); // 向指定文件中输出信息
void copy(char *, char *, int); // 将参数2中的数据复制到参数1中,参数3为长度
int proofreadIbsn(char *); // 判断isbn号的合法性
int sole(char *); // 判断指定isbn的唯一性,比较链表中的结点中存的值
int proofreadDate(char *); // 判断日期的合法性
void countsAuthors(); // 统计 作者:书的数量
void conntsPublishers(); // 统计 出版社:书的数量
// 全局
PBOOKS pHead = NULL; // 链表头节点
PBOOKS pTail = NULL; // 尾结点
// 主函数
int main(int argc, char const *argv[])
{
int option = 10;
createLinked(); // 初始化链表
while (option)
{
Interface(); // 打印菜单
scanf("%d", &option); // 输入选项 ,输入0退出
fflush(stdin);
switch (option)
{
case 1:
system("CLS");
add();
option = 10;
break;
case 2:
system("CLS");
findIsbn();
option = 10;
break;
case 3:
system("CLS");
findName();
option = 10;
break;
case 4:
system("CLS");
isbnUpdate();
option = 10;
break;
case 5:
system("CLS");
isbnDelete();
option = 10;
break;
case 6:
system("CLS");
conntsPublishers();
option = 10;
break;
case 7:
system("CLS");
countsAuthors();
option = 10;
break;
case 8:
system("CLS");
inputFile();
option = 10;
break;
case 9:
system("CLS");
outputFile();
option = 10;
break;
case 0:
system("CLS");
exit(-1);
break;
default:
system("CLS");
printf("输入不能识别,请输入正确的选项!\n");
option = 10;
break;
}
}
return 0;
}
void Interface()
{
printf("====================图书登记管理程序====================\n");
printf(" -->(1) 添加书本信息\n");
printf(" -->(2) 通过书号(ISBN),查看书本信息\n");
printf(" -->(3) 通过作者名,查看其所有书本信息\n");
printf(" -->(4) 通过书号(ISBN),修改书本信息\n");
printf(" -->(5) 通过书号(ISBN),删除书本信息\n");
printf(" 扩展:\n");
printf(" -->(6) 统计 按(出版社)分类-->计数\n");
printf(" -->(7) 统计 按(作者)分类-->计数\n");
printf(" -->(8) 从文件读入书本信息\n");
printf(" -->(9) 将信息输出到文件\n");
printf(" -->(0) 退出此程序\n");
printf("\n请输入你的选择:");
}
void createLinked()
{
pHead = (PBOOKS)malloc(sizeof(BOOKS)); // 生成1个结点,做头节点
if (pHead == NULL)
{
printf("分配失败,程序终止\n");
exit(-1);
}
pTail = pHead; // Tail中的地址是头节点
pTail->nextBooks = NULL;
return;
}
void add()
{
printf("====================图书登记管理程序====================");
printf("\n已进入添加书本信息选项中:\n");
int i = 0;
char input = 'y';
while (input == 'y')
{
PBOOKS pNew = (PBOOKS)malloc(sizeof(BOOKS)); // PBOOKS pNew 表示 struct Node * ; pNew 每次循环生成一个结点,将地址赋给pNew,进行处理
if (pNew == NULL)
{
printf("分配失败,程序终止\n");
exit(-1);
}
printf("请输入ISBN(例:978-962-215-001-0):");
fflush(stdin);
scanf("%s", &(pNew->isbn));
int flag = 3;
if (proofreadIbsn(pNew->isbn) && sole(pNew->isbn)) // 判断isbn的正确性
{
printf("校验成功\n"); // 合法,不做处理
}
else
{
while ((!(proofreadIbsn(pNew->isbn) && sole(pNew->isbn))) && --flag) // 合法返回1,取反,循环结束
{
memset(pNew->isbn, '\0', sizeof(pNew->isbn)); // 初始化 内存中的值
// printf("\n多次输入错误%d\n",flag);
printf("\n输入的ISBN有误,请重新输入\n");
printf("请输入ISBN(例:978-962-215-001-0):");
fflush(stdin);
scanf("%s", &(pNew->isbn));
}
if (flag == 0)
{
printf("\n多次输入错误,自动退出\n");
return;
}
printf("校验成功\n");
}
printf("请输入书名:");
fflush(stdin);
scanf("%s", &(pNew->name));
printf("请输入作者:");
fflush(stdin);
memset(pNew->author, '\0', sizeof(pNew->author)); // 初始化 内存中的值
scanf("%s", &(pNew->author));
printf("请输入价格:");
fflush(stdin);
scanf("%f", &(pNew->price));
printf("请输入出版社:");
fflush(stdin);
memset(pNew->publisher, '\0', sizeof(pNew->publisher)); // 初始化 内存中的值
scanf("%s", &(pNew->publisher));
printf("请输入出版日期(例:20201212):");
fflush(stdin);
scanf("%s", &(pNew->date));
if (proofreadDate(pNew->date)) // 判断日期的正确性
{
printf("校验成功\n"); // 合法,不做处理
}
else
{
flag = 3;
while (!proofreadDate(pNew->date) && --flag) // 合法返回1,取反,循环结束,多次输入错误,退出
{
memset(pNew->date, '\0', sizeof(pNew->date)); // 初始化 内存中的值
printf("\n输入的日期有误,请重新输入\n");
printf("请输入出版日期(例:20201212):");
fflush(stdin);
scanf("%s", &(pNew->date));
}
if (flag == 0)
{
printf("\n多次输入错误,自动退出\n");
return;
}
printf("校验成功\n");
}
pNew->nextBooks = NULL;
pTail->nextBooks = pNew; // 第一次循环时,pTail中的地址是头节点,第二次循环时pTail中的地址是 第一次循环时生成的pNew中的地址
pTail = pNew; // 最新的结点充当尾结点
printf("\n继续输入信息,请输入y,结束输入任意字符:");
fflush(stdin);
scanf("%c", &input);
i++;
}
printf("添加%d条数据\n", i);
return;
}
void findIsbn()
{
printf("====================图书登记管理程序====================");
printf("\n已进入通过书号(ISBN),查看书本信息选项中:\n");
char isbnN[18];
PBOOKS p = pHead->nextBooks; // 头指针->next(头节点的指针域),首结点
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
}
else
{
printf("请输入你要查找的ISBN:");
memset(isbnN, '\0', sizeof(isbnN));
fflush(stdin);
scanf("%s", &isbnN);
while (p != NULL) // 遍历
{
if (isbnEqual(p->isbn, isbnN, 18)) // 比较字符数组中的内容
{
printf("\nISBN\t\t\t书名\t作者\t出版社\t\t价格\t出版日期\n");
printf("%s\t%s\t%s\t%s\t%.2f\t%s\n\n", p->isbn, p->name, p->author, p->publisher, p->price, p->date);
return;
}
else
{
p = p->nextBooks;
}
}
printf("\n程序中没有找到书本\n");
}
return;
}
int isbnEqual(char *a, char *b, int len)
{
int result = 0;
int i;
for (i = 0; i < len - 1; i++)
{
if (*(a + i) == *(b + i))
{
result++;
// printf("\n比对下标%d位%c^%c\n",i,*(a + i),*(b + i));
}
else
{
return 0;
}
}
return result;
}
void copy(char *a, char *b, int len)
{
int i;
for (i = 0; i < len - 1; i++)
{
*(a + i) = *(b + i);
}
return;
}
int proofreadDate(char *a)
{
// 下面只是简单的判断一下,没有考虑年、月份里的准确天数 (合理的应该是判断闰年,月份准确的有多少天)
// 20201201 长度8,每位都是数字,以1、2开头,第5位为0、1,第6位0~9(当第5位为1时,第6位取1、2),第7位 0、1、2、3,第8位0~9(当第7位为3时,第8位取1、0)
if (strlen(&(*a)) != 8)
{
return 0;
}
int i;
for (i = 0; i < 8; i++) // 下标0~7
{
if (*(a + i) >= '0' && *(a + i) <= '9') // 每位都是数字
{
;
}
else
{
return 0;
}
}
if (*(a) == '1' || *(a) == '2') // 下面判断 具体情况 1,2
{
if (*(a + 4) == '0' || (*(a + 4) == '1' && (*(a + 5) == '0' || *(a + 5) == '1' || *(a + 5) == '2'))) // 5,6
{
if (*(a + 6) >= '0' && *(a + 6) < '3' || *(a + 6) == '3' && ( *(a + 7) == '1'|| *(a + 7) == '0') )
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
return 0;
}
}
int proofreadIbsn(char *a)
{
// printf("调用过"); // 测试时用
// 只简单的判断一下,不准确
// ISBN 978-962-215-001-0 , 数字开头与结尾,13位,4个分隔符
if (strlen(&(*a)) != 17)
{
// printf("\n长度为%d",strlen(a));
return 0;
}
int s = 0, f = 0;
int i;
for (i = 0; i < 17; i++) // 下标0~16
{
if (*(a + i) >= '0' && *(a + i) <= '9')
{
s++;
// printf("\n%d,\n",s);
}
else
{
if (*(a + i) == '-' && i != 0 && i != 16)
{
f++;
// printf("\n,%d\n",f);
if (*(a + i) == '-' && *(a + i + 1) == '-') // 两位连续是'-'时,错误
{
// printf("连续");
return 0;
}
}
else
{
return 0;
}
}
}
if (s == 13 && f == 4)
{
// printf("proofreadIbsn\n");
return 1;
}
}
int sole(char *a) // 唯一性
{
// 遍历,对比
PBOOKS p = pHead->nextBooks; // 首结点
if (p == NULL)
{
// printf("sole\n");
return 1;
}
while (p != NULL) // 遍历
{
if (isbnEqual(p->isbn, a, 18)) // 为真时,表示相等,重复了
{
// printf("noSole\n");
return 0;
}
else
{
p = p->nextBooks;
}
}
// printf("sole\n");
return 1;
}
void findName()
{
printf("====================图书登记管理程序====================");
printf("\n已进入通过作者名,查看其所有书本信息选项中:\n");
char authorN[20];
int count = 0;
PBOOKS p = pHead->nextBooks; // 头指针->next(头节点的指针域)
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
}
else
{
printf("请输入你要查找的作者:");
fflush(stdin);
scanf("%s", &authorN);
while (p != NULL) // 遍历
{
if (strcmp(p->author, authorN) == 0) // 比较数组中的内容
{
count++;
printf("\nISBN\t\t\t书名\t作者\t出版社\t\t价格\t出版日期\n");
printf("%s\t%s\t%s\t%s\t%.2f\t%s\n", p->isbn, p->name, p->author, p->publisher, p->price, p->date);
p = p->nextBooks;
}
else
{
p = p->nextBooks;
}
}
if (!count)
{
printf("\n程序中没有找到与此作者相关书本\n");
}
}
return;
}
void isbnUpdate()
{
printf("====================图书登记管理程序====================");
printf("\n通过书号(ISBN),修改书本信息选项中:\n");
char isbnN[18];
char temp_isbn[18];
char temp_date[9];
PBOOKS p = pHead->nextBooks; // 头指针->next(头节点的指针域)
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
}
else
{
printf("请输入你要查找的ISBN:");
memset(isbnN, '\0', sizeof(isbnN));
fflush(stdin);
scanf("%s", &isbnN);
while (p != NULL) // 遍历
{
if (isbnEqual(p->isbn, isbnN, 18)) // 输入的isbn与链表中的isbn 遍历比较
{
int flag = 10;
int sign = 3;
while (flag)
{
printf("\nISBN\t\t\t书名\t作者\t出版社\t\t价格\t出版日期\n");
printf("%s\t%s\t%s\t%s\t%.2f\t%s\n", p->isbn, p->name, p->author, p->publisher, p->price, p->date);
memset(temp_isbn, '\0', sizeof(temp_isbn)); // 初始化 内存中的值
memset(temp_date, '\0', sizeof(temp_date));
copy(temp_isbn, p->isbn, 18);
copy(temp_date, p->date, 9);
printf("\n需要修改哪一项内容?(1.ISBN 2.书名 3.作者 4.出版社 5.价格 6.出版日期\n或输入其它任意字符退出,请输入:");
fflush(stdin);
scanf("%d", &flag);
switch (flag)
{
case 1:
flag = 10;
printf("请输入ISBN:");
fflush(stdin);
scanf("%s", isbnN);
// 合法性校验
sign = 3;
while (((proofreadIbsn(isbnN) == 0) || (sole(isbnN) == 0)) && --sign) // 满足所有条件,多次输入错误,退出
{
memset(isbnN, '\0', sizeof(isbnN)); // 初始化 内存中的值
printf("\n输入的ISBN有误,请重新输入\n");
printf("请输入ISBN(例:978-962-215-001-0):");
fflush(stdin);
scanf("%s", &(isbnN));
}
copy(p->isbn, isbnN, 18);
if (sign == 0)
{
memset(p->isbn, '\0', sizeof(p->isbn)); // 初始化 内存中的值
copy(p->isbn, temp_isbn, 18);
printf("\n多次输入有误,数据未更改\n");
break;
}
printf("\n修改成功\n");
break;
case 2:
flag = 10;
printf("\n请输入书名:");
fflush(stdin);
scanf("%s", p->name);
printf("\n修改成功\n");
break;
case 3:
flag = 10;
printf("\n请输入作者:");
fflush(stdin);
scanf("%s", p->author);
printf("\n修改成功\n");
break;
case 4:
flag = 10;
printf("\n请输入出版社:");
fflush(stdin);
scanf("%s", p->publisher);
printf("\n修改成功\n");
break;
case 5:
flag = 10;
printf("\n请输入价格:");
fflush(stdin);
scanf("%f", &p->price);
printf("\n修改成功\n");
break;
case 6:
flag = 10;
printf("\n请输入出版日期:");
fflush(stdin);
scanf("%s", p->date);
// 合法性校验
sign = 3;
while (!proofreadDate(p->date) && --sign) // 合法返回1,取反,循环结束
{
memset(p->date, '\0', sizeof(p->date)); // 初始化 内存中的值
printf("\n输入的日期有误,请重新输入\n");
printf("请输入出版日期(例:20201212):");
fflush(stdin);
scanf("%s", &(p->date));
}
if (sign == 0)
{
memset(p->date, '\0', sizeof(p->date)); // 初始化 内存中的值
copy(p->date, temp_date, 9);
printf("\n多次输入有误,数据未更改\n");
break;
}
printf("\n修改成功\n");
break;
default:
return;
}
}
}
else
{
p = p->nextBooks;
}
}
printf("\n程序中没有找到书本\n");
}
return;
}
void isbnDelete()
{
printf("====================图书登记管理程序====================");
printf("\n已进入通过书号(ISBN),删除书本信息选项中:\n");
char isbnN[18];
PBOOKS p = pHead->nextBooks; // 首结点
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
}
else
{
PBOOKS temp = pHead; // 头节点
printf("请输入你要删除的ISBN:");
scanf("%s", &isbnN);
fflush(stdin);
while (p != NULL) // 遍历
{
if (isbnEqual(p->isbn, isbnN, 18)) // 比较字符数组中的内容
{
temp->nextBooks = p->nextBooks; // temp结点 比 p结点慢一步
free(p); // 释放被删除的结点内存
printf("\n删除成功\n");
if (temp->nextBooks == NULL)
{
pTail = temp;
}
return;
}
else
{
p = p->nextBooks;
temp = temp->nextBooks;
}
}
printf("\n程序中没有找到书本\n");
}
return;
}
void inputFile()
{
printf("====================图书登记管理程序====================");
printf("\n已进从文件读入书本信息选项中:\n");
FILE *fp = NULL;
// char *a = "D:\\E_disk\\tes.txt";
char path[50];
// 1. 输入读取路径
fflush(stdin);
printf("\n请输入读取文件路径,可参考(D:\\A\\b.txt):");
scanf("%s", path);
printf("指定的路径为:%s", path);
// 2. 读取文件
fp = fopen(path, "r"); // r 只读,文件不存在就出错
if (fp == NULL)
{
printf("\n读取文件失败\n");
return;
}
else
{
printf("\n成功读入文件...正在处理\n");
// 临时变量
char isbn[18];
char name[20];
char author[9];
char publisher[30];
float price;
char date[9]; // 时间格式20201221
// 4. 从文件里依次取值 , 循环读取全部数据
int count = 0;
printf("\nISBN\t\t\t书名\t作者\t出版社\t\t价格\t出版日期\n");
while (!feof(fp)) // 文件结束:返回非0值;文件未结束:返回0值
{
// 3. 读取数据前,先创建一个结点
PBOOKS pNew = (PBOOKS)malloc(sizeof(BOOKS));
if (pNew == NULL)
{
printf("\n分配失败,程序终止\n");
printf("\n已添加%d条数据\n", count);
return;
}
memset(isbn, '\0', sizeof(isbn)); // 初始化 内存中的值
memset(name, '\0', sizeof(name));
memset(author, '\0', sizeof(author));
memset(publisher, '\0', sizeof(publisher));
memset(&price, '\0', sizeof(price));
memset(date, '\0', sizeof(date));
memset(pNew->isbn, '\0', sizeof(pNew->isbn)); // 初始化 内存中的值
memset(pNew->name, '\0', sizeof(pNew->name));
memset(pNew->author, '\0', sizeof(pNew->author));
memset(pNew->publisher, '\0', sizeof(pNew->publisher));
memset(&(pNew->price), '\0', sizeof(pNew->price));
memset(pNew->date, '\0', sizeof(pNew->date));
// 读取数据
fscanf(fp, "%s %s %s %s %f %s\n", isbn, name, author, publisher, &price, date);
// 赋值前,进行数据的检验
if ((proofreadIbsn(isbn) && sole(isbn)) == 0) // 判断isbn的正确性
{
system("CLS");
printf("\n本次操作添加了%d条数据\n", count);
printf("\n从文件中读入的数据(ISBN)有误,禁止写入数据\n\n");
return;
}
if (proofreadDate(date) == 0) // 判断日期的正确性
{
system("CLS");
printf("\n本次操作添加了%d条数据\n", count);
printf("\n从文件中读入的数据(日期)有误,禁止写入数据\n\n");
return;
}
// 临时值读取成功后赋值给结点,c语言中 两个数组之间不能直接赋值
copy(pNew->isbn, isbn, 18);
copy(pNew->name, name, 20);
copy(pNew->author, author, 9);
copy(pNew->publisher, publisher, 30);
pNew->price = price;
copy(pNew->date, date, 9);
printf("%s\t%s\t%s\t%s\t%.2f\t%s\n", pNew->isbn, pNew->name, pNew->author, pNew->publisher, pNew->price, pNew->date);
// 结点插入到链表后面
pNew->nextBooks = NULL;
pTail->nextBooks = pNew;
pTail = pNew;
count++;
}
printf("\n本次操作添加了%d条数据\n", count);
// 关闭文件
fclose(fp);
}
return;
}
void outputFile()
{
printf("====================图书登记管理程序====================");
printf("\n已进将信息输出到文件选项中:\n");
FILE *fp = NULL;
// char *path = "D:\\E_disk\\output.txt";
char path[50];
// 1. 输入读取路径
fflush(stdin);
printf("\n请输入要输出文件路径,可参考(D:\\A\\c.txt):");
scanf("%s", path);
printf("指定的路径为:%s", path);
// 2. 读取文件
fp = fopen(path, "a"); // a 追加,文件不存会自己创建
// setbuf(fp, NULL);
if (fp == NULL)
{
printf("\n路径读取出现问题\n");
return;
}
else
{
printf("\n成功读取路径..正在处理\n");
}
// 2. 遍历输出链表结点
PBOOKS p = pHead->nextBooks; // 首结点
if (p == NULL)
{
printf("\n程序中没有数据\n");
}
else
{
printf("\n正在输出数据...\n");
int count = 0;
fprintf(fp, "ISBN\t\t\t书名\t作者\t出版社\t\t价格\t出版日期\n");
fflush(fp);
while (p != NULL) // 遍历
{
count++;
// 把输出结果保存到文件
fprintf(fp, "%s\t%s\t%s\t%s \t%.2f\t%s\n", p->isbn, p->name, p->author, p->publisher, p->price, p->date);
fflush(fp);
p = p->nextBooks;
}
printf("\n共%d条数据写入到文件\n", count);
}
fclose(fp);
return;
}
void countsAuthors()
{
printf("====================图书登记管理程序====================");
printf("\n已进统计 按(作者)分类-->计数选项中:\n");
typedef struct authors // 作者名,以链表存储,
{
char name[9];
int n;
struct authors *nextAutors;
} AUTHORS, *PAUTHORS;
PAUTHORS pHead_au = NULL;
PAUTHORS pTail_au = NULL;
pHead_au = (PAUTHORS)malloc(sizeof(AUTHORS)); // 头节点
pTail_au = pHead_au; // 最开始 尾结点与头结点指向同一地址
pTail_au->nextAutors = NULL;
PAUTHORS pHead_temp = pHead_au->nextAutors;
PBOOKS p = pHead->nextBooks; // 首结点
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
return;
}
else
{
while (p != NULL) // 遍历
{
// 判断 p->authors 在 p_au 中的 是否存在
if (pHead_au->nextAutors == NULL) // 不存在直接插入新结点,计数1
{
PAUTHORS pNew_au = (PAUTHORS)malloc(sizeof(AUTHORS));
memset(pNew_au->name, '\0', sizeof(pNew_au->name));
copy(pNew_au->name, p->author, 9);
pNew_au->nextAutors = NULL;
pNew_au->n = 1;
pTail_au->nextAutors = pNew_au;
pTail_au = pNew_au;
// printf("\n情况1\n");
}
else
{
pHead_temp = pHead_au->nextAutors; // 首结点
while (pHead_temp != NULL)
{
if (isbnEqual(p->author, pHead_temp->name, 9)) // 存在 计数加1
{
pHead_temp->n += 1;
// printf("\n情况2\n");
goto TiaoChu;
}
pHead_temp = pHead_temp->nextAutors;
}
// 不存在,插入新结点,计数1
PAUTHORS pNew_au = (PAUTHORS)malloc(sizeof(AUTHORS));
memset(pNew_au->name, '\0', sizeof(pNew_au->name));
copy(pNew_au->name, p->author, 9);
pNew_au->nextAutors = NULL;
pNew_au->n = 1;
// printf("\n情况3\n");
pTail_au->nextAutors = pNew_au;
pTail_au = pNew_au;
}
TiaoChu:
p = p->nextBooks;
}
}
pHead_temp = pHead_au->nextAutors; // 首结点
printf("\n统计数据(作者名:书本数量):\n");
while (pHead_temp != NULL) // 遍历
{
fflush(stdout);
printf("\n%s:%d\n", pHead_temp->name, pHead_temp->n);
pHead_temp = pHead_temp->nextAutors;
}
return;
}
void conntsPublishers()
{
printf("====================图书登记管理程序====================");
printf("\n已进统计 按(出版社)分类-->计数选项中:\n");
typedef struct publisher // 出版社名,以链表存储,
{
char name[30];
int n;
struct publisher *nextPublisher;
} PUBLISHER, *PPUBLISHER;
PPUBLISHER pHead_pu = NULL;
PPUBLISHER pTail_pu = NULL;
pHead_pu = (PPUBLISHER)malloc(sizeof(PUBLISHER)); // 头节点
pTail_pu = pHead_pu; // 最开始 尾结点与头结点指向同一地址
pTail_pu->nextPublisher = NULL;
PPUBLISHER pHead_temp = pHead_pu->nextPublisher; // 首结点
PBOOKS p = pHead->nextBooks; // 首结点
if (p == NULL) // 没有首结点
{
printf("\n程序中暂未存储数据\n");
return;
}
else
{
while (p != NULL) // 遍历
{
// 判断 p->publisheers 在 p_pu 中的 是否存在
if (pHead_pu->nextPublisher == NULL) // 不存在直接插入新结点,计数1
{
PPUBLISHER pNew_pu = (PPUBLISHER)malloc(sizeof(PUBLISHER));
memset(pNew_pu->name, '\0', sizeof(pNew_pu->name));
copy(pNew_pu->name, p->publisher, 30);
pNew_pu->nextPublisher = NULL;
pNew_pu->n = 1;
pTail_pu->nextPublisher = pNew_pu;
pTail_pu = pNew_pu;
// printf("\n情况1\n");
}
else
{
pHead_temp = pHead_pu->nextPublisher; // 首结点
while (pHead_temp != NULL)
{
if (isbnEqual(p->publisher, pHead_temp->name, 30)) // 存在 计数加1
{
pHead_temp->n += 1;
// printf("\n情况2\n");
goto TiaoChu;
}
pHead_temp = pHead_temp->nextPublisher;
}
// 不存在,插入新结点,计数1
PPUBLISHER pNew_pu = (PPUBLISHER)malloc(sizeof(PUBLISHER));
memset(pNew_pu->name, '\0', sizeof(pNew_pu->name));
copy(pNew_pu->name, p->publisher, 30);
pNew_pu->nextPublisher = NULL;
pNew_pu->n = 1;
// printf("\n情况3\n");
pTail_pu->nextPublisher = pNew_pu;
pTail_pu = pNew_pu;
}
TiaoChu:
p = p->nextBooks;
}
}
pHead_temp = pHead_pu->nextPublisher; // 首结点
printf("\n统计数据(出版社名:书本数量):\n");
while (pHead_temp != NULL) // 遍历
{
fflush(stdout);
printf("\n%s:%d\n", pHead_temp->name, pHead_temp->n);
pHead_temp = pHead_temp->nextPublisher;
}
return;
}