Library.h
#ifndef Library_H
#define Library_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char loginNo[10]; //登录号
char name[20]; //书名
char author[16]; //作者名
char classNo[10]; //分类号
char publisher[20]; //出版单位
char pubTime[11]; //出版时间
float price; //价格
}BookInfo; //图书信息结构体
#define MAX 100
bool CheckDate(char b[]); //检查日期是否出错
bool CheckloginNo(BookInfo *book, int m, char no[]); //检查登录号是否有重复
void InputEmploy(BookInfo *&book, int& n); //1)单记录输入:以列方式输入图书多记录信息
void MultiInputEmploy(BookInfo *&book, int& m); //1)多记录输入:以行方式输入图书多记录信息
void DispBook(BookInfo *&book, int n); //2)图书信息浏览模块
void SortloginNo(BookInfo *book, int m); //3)递增排序:按登录号排序,采用直接插入排序
void BubbleSort(BookInfo *book, int m); //3)递增排序:按分类号排序,采用冒泡排序
void SelectSort(BookInfo *book, int m); //3)递增排序:按价格排序,采用简单选择排序
bool SearchBook(BookInfo *book, int n); //4)查询图书信息
bool DeleteBook(BookInfo *&book, int& n); //5)删除图书信息
bool ModifyBook(BookInfo *&book, int n); //6)修改图书信息
int menu(); //菜单
bool SaveFile(BookInfo *&book, int n); //保存数据到文件中
bool ReadFile(BookInfo *book, int &n); //读文件数据模块
#endif // !_Library_H
Librarymain.cpp
#include "Library.cpp"
int main()
{
BookInfo book[MAX] = {};
int select = 0;
int n = 0;
ReadFile(book, n); //从文件中读取数据
for(;;)
{
switch (menu())
{
case 1:
printf("请选择输入方式:1. 输入单条记录 2. 输入多条记录\n");
scanf_s("%d", &select);
printf("\n");
if (select == 1)
InputEmploy(book, n); //输入单条记录
else
MultiInputEmploy(book, n); //输入多条记录
break;
case 2:
DispBook(book, n);
break;
case 3:
select = 9;
while (select != 0)
{
//构造二级菜单
printf("\n");
printf("递增排序子菜单\n");
printf("1. 按登录号排序\n");
printf("2. 按分类号排序\n");
printf("3. 按价格排序\n");
printf("4. 浏览图书信息\n");
printf("0. 返回上级菜单\n");
printf("请输入选择(0-4):");
scanf_s("%d", &select);
printf("\n");
//调用菜单模块
switch (select)
{
case 1:
SortloginNo(book, n);
break;
case 2:
BubbleSort(book, n);
break;
case 3:
SelectSort(book, n);
break;
case 4:
DispBook(book, n);
break;
case 0:
break;
}
}
break;
case 4:
SearchBook(book, n);
break;
case 5:
DeleteBook(book, n);
break;
case 6:
ModifyBook(book, n);
break;
case 0:
exit(0);
default:
printf("\t\t输入错误!请重新输入!\n");
break;
}
}
return 0;
}
Library.cpp
#include "Library.h"
//检查日期是否出错
bool CheckDate(char b[])
{
int year;
int month;
int day;
int k;
int standday;
year = 0;
for (k = 0; k <= 3; k++)
year = year * 10 + (b[k] - '0'); //得到年份
month = 0;
for (k = 5; k <= 6; k++)
month = month * 10 + (b[k] - '0'); //得到月份
day = 0;
for (k = 8; k <= 9; k++)
day = day * 10 + (b[k] - '0'); //得到日期
if (year <= 1949 || year>=2020) //判断年份是否合理
return 0;
if (month < 1 || month>12) //判断月份是否合理
return 0;
if (day < 1 || day>31) //判断日期是否合理
return 0;
switch (month)
{
case 2:
//判断是否闰年,闰年二月29天,平年二月28天
if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
standday = 29;
else
standday = 28;
if (day > standday)
return 0;
break;
//月小30天
case 4:
case 6:
case 9:
case 11:
if (day > 30)
return 0;
break;
}
return 1;
}
//检查登录号是否有重复
bool CheckloginNo(BookInfo *book, int m, char no[])
{
int k = 0;
for (k = 0; k < m; k++)
if (strcmp(book[k].loginNo, no) == 0) //判断登录号是否重复
return 0;
return 1;
}
//1)单记录输入:以列方式输入图书多记录信息
void InputEmploy(BookInfo *&book, int& n)
{
char IsInput;
bool legal;
int length = 10;
char num[MAX] = {0};
char str[MAX] = {0};
printf("请输入图书信息\n");
IsInput = 'y';
do
{
//登录号查重
do
{
printf("登录号(例:000):");
scanf_s("%s", &num, 10);
legal = CheckloginNo(book, n, num);
if (!legal)
printf("输入重复登录号,请重新输入!\n");
} while (!legal);
strcpy_s(book[n].loginNo, num);
printf("书名:");
scanf_s("%s", &book[n].name, 20);
printf("作者名:");
scanf_s("%s", &book[n].author, 10);
printf("分类号 :");
scanf_s("%s", &book[n].classNo, 10);
printf("出版单位 :");
scanf_s("%s", &book[n].publisher, 20);
//出版日期合法性检测
legal = 1;
do
{
printf("出版时间 (YYYY-MM-DD):");
scanf_s("%s", &str, 11);
//长度合法性检查
length = strlen(str);
if (length < 10)
printf("输入长度不够,请重新输入!\n");
if (length > 10)
printf("输入长度过长,请重新输入!\n");
//日期值的合法性检查
legal = CheckDate(str);
if (!legal && length == 10)
printf("输入日期不合法,请重新输入!\n");
} while (length != 10 || !legal);
strcpy_s(book[n].pubTime, str);
printf("价格 :");
scanf_s("%f", &book[n].price);
printf("是否继续输入(y/n):");
getchar();
scanf_s("%c", &IsInput, 10);
n++;
} while (IsInput != 'n' && IsInput != 'N');
//保存数据到文件中
if (SaveFile(book, n))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
//1)多记录输入:以行方式输入图书多记录信息
void MultiInputEmploy(BookInfo *&book, int& m)
{
int j = 0;
int num, length; //存储记录数和字符长度
char strlogin[10] = { 0 }; //存储输入的登录号
char strname[20] = { 0 }; //存储输入的书名
char strauthor[16] = { 0 }; //存储输入的作者名
char strclass[10] = { 0 }; //存储输入的分类号
char strpublisher[20] = { 0 }; //存储输入的出版单位
char strtime[11] = { 0 }; //存储输入的出版时间
float sal = 0; //存储输入的价格
bool legal1, legal2; //分别存储登录号和出版日期的合法性
printf("现有图书记录条数%d:\n", m);
printf("请输入本次录入记录条数:");
scanf_s("%d", &num);
printf("********按行输入,注意登录号和出版日期。如果数据错误,则需要退回重输!********\n");
printf("********登录号例:000,出版日期在1950-01-01与2019-12-31之间********\n");
printf("登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
do
{
printf("输入第%d条记录:\n", m + 1);
scanf_s("%s %s %s %s %s %s %f", &strlogin, 10, strname, 20, &strauthor, 16, &strclass, 10,
&strpublisher, 20, &strtime, 11, &sal);
//登录号合法性检查模块,这里主要查重
legal1 = 1;
legal1 = CheckloginNo(book, m, strlogin);
if (!legal1)
printf("输入登录号重复,请重新输入!\n");
//日期长度合法性检查
legal2 = 1;
length = strlen(strtime);
if (length < 10)
{
printf("输入长度不够,请重新输入!\n");
legal2 = 0;
}
if (length > 10)
{
printf("输入长度过长,请重新输入!\n");
legal2 = 0;
}
//日期值的合法性检查
if (legal2)
legal2 = CheckDate(strtime);
if (!legal2 && length == 10)
printf("输入日期不合法,请重新输入!\n");
//合法数据才计数
if (legal1 && legal2)
{
strcpy_s(book[m].loginNo, strlogin);
strcpy_s(book[m].name, strname);
strcpy_s(book[m].author, strauthor);
strcpy_s(book[m].classNo, strclass);
strcpy_s(book[m].publisher, strpublisher);
strcpy_s(book[m].pubTime, strtime);
book[m].price = sal;
m++;
j++;
}
} while (j < num);
//保存数据到文件中
if (SaveFile(book, m))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
//2)图书信息浏览模块
void DispBook(BookInfo *book, int n)
{
printf("所有图书信息:\n");
printf("登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
for (int i = 0; i < n; i++)
{
printf("%s", book[i].loginNo);
printf("%18s", book[i].name);
printf("%16s", book[i].author);
printf("%12s", book[i].classNo);
printf("%18s", book[i].publisher);
printf("%14s\t", book[i].pubTime);
printf("%4.2f\n", book[i].price);
}
}
//3)递增排序:按登录号排序,采用直接插入排序
void SortloginNo(BookInfo *book, int m)
{
int i = 0;
int j = 0;
BookInfo temp;
for (i = 1; i < m; i++)
{
if (strcmp(book[i - 1].loginNo, book[i].loginNo) > 0)
{
temp = book[i];
j = i - 1;
while (j >= 0 && strcmp(book[j].loginNo, temp.loginNo) > 0)
{
book[j + 1] = book[j];
j--;
};
book[j + 1] = temp;
}
printf("第%d趟排序结果\n", i);
DispBook(book, m);
}
if (SaveFile(book, m))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
//3)递增排序:按分类号排序,采用冒泡排序
void BubbleSort(BookInfo *book, int m)
{
int i, j;
bool flag = 1;
BookInfo temp;
for (i = 0; i < m - 1 && flag; i++)
{
flag = 0;
for (j = m - 1; j > i; j--)
if (strcmp(book[j].classNo, book[j - 1].classNo) < 0)
{
temp = book[j];
book[j] = book[j - 1];
book[j - 1] = temp;
flag = 1;
}
printf("第%d趟排序结果\n", i + 1);
DispBook(book, m);
}
if (SaveFile(book, m))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
//3)递增排序:按价格排序,采用简单选择排序
void SelectSort(BookInfo *book, int m)
{
int i = 0;
int j = 0;
int k = 0;
BookInfo temp;
for (i = 0; i < m - 1; i++)
{
k = i;
for (j = i + 1; j < m; j++)
if (book[j].price < book[k].price) //找出最小值
k = j;
if (k != i)
{
temp = book[i];
book[i] = book[k];
book[k] = temp;
} //将最小值放在首位
printf("第%d趟排序结果\n", i + 1);
DispBook(book, m);
}
//保存数据到文件中
if (SaveFile(book, m))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
//4)查询图书信息(范围查询和模糊查询)
bool SearchBook(BookInfo *book, int n)
{
int i = 0;
float min = 0;
float max = 0;
int menu = 0;
char str[22] = { 0 };
char str1[11] = { 0 };
char str2[11] = { 0 };
bool flag = 0;
bool legal = 0;
int length = 10;
menu = 9;
while (menu != 0)
{
flag = 0;
printf("\n查询选项:1、价格 2、书名 3、作者名 4、出版日期 0. 返回上级菜单 \n");
printf("请输入你的选择(0-4):");
scanf_s("%d", &menu);
switch (menu)
{
case 1:
//按价格查询,范围查找
printf("请输入查找的价格范围:\n");
printf("最低价格为");
scanf_s("%f", &min);
printf("最高价格为");
scanf_s("%f", &max);
printf("要查找的价格范围是:%4.2f<=价格<=%4.2f\n", min, max);
printf("符合条件的信息有:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
for (i = 0; i < n; i++)
{
if (book[i].price >= min && book[i].price <= max)
{
printf("%-14d", i + 1);
printf("%s", book[i].loginNo);
printf("%18s", book[i].name);
printf("%16s", book[i].author);
printf("%12s", book[i].classNo);
printf("%18s", book[i].publisher);
printf("%14s\t", book[i].pubTime);
printf("\t%4.2f\n", book[i].price);
flag = 1;
}
}
if (flag == 0)
printf("图书不存在\n");
break;
case 2:
//按书名查询,模糊查询
printf("请输入查找的书名(可以模糊查询):");
scanf_s("%s", &str, 22);
printf("要查找的书名姓名是:%s\n", str);
printf("符合条件的记录:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
for (i = 0; i < n; i++)
{
if (strstr(book[i].name, str))//实现模糊查询
{
printf("%-14d", i + 1);
printf("%s", book[i].loginNo);
printf("%18s", book[i].name);
printf("%16s", book[i].author);
printf("%12s", book[i].classNo);
printf("%18s", book[i].publisher);
printf("%14s\t", book[i].pubTime);
printf("\t%4.2f\n", book[i].price);
flag = 1;
}
}
if (flag == 0)
printf("图书不存在\n");
break;
case 3:
//按作者姓名查询,模糊查询
printf("请输入查找的作者姓名(可以模糊查询):");
scanf_s("%s", &str, 12);
printf("要查找的作者姓名是:%s\n", str);
printf("符合条件的记录:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
for (i = 0; i < n; i++)
{
if (strstr(book[i].author, str))//实现模糊查询
{
printf("%-14d", i + 1);
printf("%s", book[i].loginNo);
printf("%18s", book[i].name);
printf("%16s", book[i].author);
printf("%12s", book[i].classNo);
printf("%18s", book[i].publisher);
printf("%14s\t", book[i].pubTime);
printf("\t%4.2f\n", book[i].price);
flag = 1;
}
}
if (flag == 0)
printf("图书不存在\n");
break;
case 4:
//按出版日期查询,范围查找
printf("请输入查找的出版日期范围(YYYY-MM-DD):\n");
//检查最早出版日期是否合理
do
{
printf("出版日期>=");
scanf_s("%s", &str1, 11);
//长度合法性检查
length = strlen(str1);
if (length < 10)
printf("输入长度不够,请重新输入!\n");
if (length > 10)
printf("输入长度过长,请重新输入!\n");
//日期值的合法性检查
legal = CheckDate(str1);
if (!legal && length == 10)
printf("输入日期不合法,请重新输入!\n");
} while (length != 10 || !legal);
//检查最早出版日期是否合理
do
{
printf("出版日期<=");
scanf_s("%s", &str2, 11);
//长度合法性检查
length = strlen(str2);
if (length < 10)
printf("输入长度不够,请重新输入!\n");
if (length > 10)
printf("输入长度过长,请重新输入!\n");
//日期值的合法性检查
legal = CheckDate(str2);
if (!legal && length == 10)
printf("输入日期不合法,请重新输入!\n");
} while (length != 10 || !legal);
printf("要查找的出版日期范围是:%s<=出版日期<=%s\n", str1, str2);
printf("符合条件的记录:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
for (i = 0; i < n; i++)
{
if (strcmp(book[i].pubTime, str1) >= 0 && strcmp(book[i].pubTime, str2) <= 0)
{
printf("%-14d", i + 1);
printf("%s", book[i].loginNo);
printf("%18s", book[i].name);
printf("%16s", book[i].author);
printf("%12s", book[i].classNo);
printf("%18s", book[i].publisher);
printf("%14s\t", book[i].pubTime);
printf("\t%4.2f\n", book[i].price);
flag = 1;
}
}
if (flag == 0)
printf("图书不存在\n");
break;
case 0:
break;
}
}
return flag;
}
//5)删除图书信息(先查询,后删除)
bool DeleteBook(BookInfo *&book, int& n)
{
int i = 0;
int no = 0;
char IsDel;
bool flag = 0;
//删除之前先进行查询操作
printf("***删除之前先进行查询操作,进行删除时选择返回上级菜单。***");
SearchBook(book, n);
printf("请输入删除的图书记录号:");
scanf_s("%d", &no);
if (no >= 1 && no <= n)
{
printf("要删除的记录是:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
printf("%-14d", no);
printf("%s", book[no - 1].loginNo);
printf("%18s", book[no - 1].name);
printf("%16s", book[no - 1].author);
printf("%12s", book[no - 1].classNo);
printf("%18s", book[no - 1].publisher);
printf("%14s\t", book[no - 1].pubTime);
printf("\t%4.2f\n", book[no - 1].price);
printf("确定删除?(Y/N):");
getchar();
IsDel = getchar();
if (IsDel == 'Y' || IsDel == 'y')
{
for (i = no - 1; i < n; i++)
book[i] = book[i + 1];
n--;
flag = 1;
}
}
else
printf("要删除的第%d条记录不存在\n", no);
if (flag)
{
//保存数据到文件中
if (SaveFile(book, n))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
return flag;
}
//6)修改图书信息(先查询,后修改)
bool ModifyBook(BookInfo *&book, int n)
{
int choice = 0;
int no = 0;
int length = 0;
float sal;
char str[20] = {0};
bool flag = 0;
bool legal = 0;
//修改之前先进行查询操作
printf("***修改之前先进行查询操作,进行修改时选择返回上级菜单。***");
SearchBook(book, n);
printf("请输入要修改的图书记录号:");
scanf_s("%d", &no);
if (no >= 1 && no <= n)
{
printf("要修改的记录是:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
printf("%-14d", no);
printf("%s", book[no - 1].loginNo);
printf("%18s", book[no - 1].name);
printf("%16s", book[no - 1].author);
printf("%12s", book[no - 1].classNo);
printf("%18s", book[no - 1].publisher);
printf("%14s\t", book[no - 1].pubTime);
printf("\t%4.2f\n", book[no - 1].price);
printf("修改选项:1、登录号 2、书名 3、作者名 4、分类号 5、出版单位 6、出版时间 7、价格 0、不修改\n");
printf("输入你的修改选择(0-7):");
scanf_s("%d", &choice);
switch (choice)
{
case 1:
//增加登录号合法性检查模块,这里主要查重
do
{
printf("输入新的登录号:");
scanf_s("%s", &str, 10);
legal = CheckloginNo(book, n, str);
if (!legal)
printf("输入登录号重复,请重新输入!\n");
} while (!legal);
strcpy_s(book[no - 1].loginNo, str);
break;
case 2:
printf("输入新的书名:");
scanf_s("%s", &str, 20);
strcpy_s(book[no - 1].name, str);
break;
case 3:
printf("输入新的作者名:");
scanf_s("%s", &str, 16);
strcpy_s(book[no - 1].author, str);
break;
case 4:
printf("输入新的分类号:");
scanf_s("%s", &str, 10);
strcpy_s(book[no - 1].classNo, str);
break;
case 5:
printf("输入新的出版单位 :");
scanf_s("%s", &str, 20);
strcpy_s(book[no - 1].publisher, str);
break;
case 6:
length = 10;
legal = 1;
do
{
printf("出版时间 (YYYY-MM-DD):");
scanf_s("%s", &str, 20);
//长度合法性检查
length = strlen(str);
if (length < 10)
printf("输入长度不够,请重新输入!\n");
if (length > 10)
printf("输入长度过长,请重新输入!\n");
//日期值的合法性检查
legal = CheckDate(str);
if (!legal && length == 10)
printf("输入日期不合法,请重新输入!\n");
if (legal && length == 10)
strcpy_s(book[no - 1].pubTime, str);
} while (length != 10 || !legal);
break;
case 7:
printf("输入新的价格:");
scanf_s("%f", &sal);
book[no - 1].price = sal;
break;
case 0:
break;
}
printf("修改后的记录是:\n");
printf("记录号 登录号 书名 作者名 分类号 出版单位 出版时间 价格\n");
printf("%-14d", no);
printf("%s", book[no - 1].loginNo);
printf("%16s", book[no - 1].name);
printf("%16s", book[no - 1].author);
printf("%14s", book[no - 1].classNo);
printf("%16s\t", book[no - 1].publisher);
printf("%16s\t", book[no - 1].pubTime);
printf("%4.2f\n", book[no - 1].price);
flag = 1;
}
else
printf("要修改的第%d条记录不存在\n", no);
//修改之后,保存数据
if (flag)
{
//保存数据到文件中
if (SaveFile(book, n))
printf("数据保存成功!\n");
else
printf("数据未能保存!\n");
}
return flag;
}
//菜单
int menu()
{
int choice = 0;
printf("\t\t*********图书信息管理系统********\n");
printf("\t\t 1、输入图书信息\n");
printf("\t\t 2、浏览图书信息\n");
printf("\t\t 3、对图书信息递增排序\n");
printf("\t\t 4、查询图书信息\n");
printf("\t\t 5、删除图书信息\n");
printf("\t\t 6、修改图书信息\n");
printf("\t\t 0. 退出\n");
printf("\t\t*********图书信息管理系统********\n");
printf("\t\t请输入选择(0-6):");
scanf_s("%d", &choice);
return choice;
}
//保存数据到文件中
bool SaveFile(BookInfo *&book, int n)
{
int i = 0;
FILE* fp;
char IsSave; //IsSave表示是否保存
//询问是否保存
printf("是否保存?(Y/N):");
getchar();
scanf_s("%c",&IsSave,10);
if (IsSave == 'N' || IsSave == 'n')
return 0;
//创建文件或打开文件
fopen_s(&fp,"Library.txt", "w+");
if (!fp)
{
printf("不能创建文件Library.txt\n");
return 0;
}
//向文件写数据
while (i < n)
{
fwrite(&book[i], sizeof(BookInfo), 1, fp);
i = i + 1;
}
fclose(fp);
return 1;
}
//读文件数据模块
bool ReadFile(BookInfo *&book, int &n)
{
FILE* fp;
BookInfo Temp;
//创建文件或打开文件
fopen_s(&fp,"Library.txt", "r+");
if (!fp)
{
printf("不能打开文件Library.txt\n");
return 0;
}
//向文件写数据
n = 0;
while (fread(&Temp, sizeof(BookInfo), 1, fp) == 1)
{
book[n] = Temp;
n++;
}
fclose(fp);
return 1;
}