二、设计方案及规划
(一)、设计方案
顺应时代的发展潮流,计算机科学的迅猛发展,科技的进步,相关行业越来越在使用电子化发展了。面对图书馆登记借阅和图书信息保存,这些工作需要纸质保存,更新效率不高,对于读者和图书管理员都比较繁琐。
因此决定,使用c语言来设计图书管理系统,更好服务于读者和管理员的工作。结合C语言知识点:变量、数组、结构体、结构体数组、循环、条件判断等,
(二)、设计规划
第一天:
画出相应的流程图,并且完成管理员使图书信息增加,并使图书编号,名称,价格等各种信息的显示功能.
第二天:
完成管理员可以使图书信息的修改,删除,功能.
第三天:
完成用户可以使用,图书单条评论功能,并显示评论,修改单条评论功能.
第四天:
使用户可以多条评论,并且实现可以修改各条评论的功能,并且显示图书的评论数及评论,管理员可以删除评论功能.
第五天:
增加用户的借阅功能,归还功能,并且使图书状态可以随用户借阅和归还而发生改变.
第六天:
增加可以使用图书名称查找功能,调试代码,使之实现以上的各种功能,制作ppt
第七天:
完善代码,进行答辩.
三、设计内容及步骤
设计内容:
- 设计管理员和用户页面
- 设计管理员的功能
- 设计用户的功能
目的:使用c语言对于图书实现智能化,实现管理员的增加、删除和修改等功能,并设计出用户的借阅、归还等功能。提高工作效率,减轻负担。
(包括目的说明和安装配置过程示意图)
安装开发工具dev C++:
1.访问Dev-C++官网.
2.运行安装程序.
3.选择偏好的语言.
4.接受许可协议.
5.选择目标文件夹.
6.选择要安装的组件.
7.创建快捷方式.
8.检查选项并开始安装.
9.等待安装完成.
10.点击完成,退出设置向导.
代码如下
#include <>
#include <>
#include <>
#define MAX_BOOK 1000
#define MAX_COMMENTS 10000
struct book//书籍信息的结构体
{
char id[10]; //图书的编号
char name[20]; //名字
int state; //图书号的状态
int cl; //库存量
float price; //图书价格
int commentcount; // 评论数
int commentids[100]; // 评论 ID 列表
int borrow_count; //图书的借出数
};
struct book book[100];//图书数组
int num=0;//图书数量
//读者信息
struct dz {
char usernum[20]; // 用户编号
char name[20];//用户姓名
char xb[20] ;//用户性别
char zh[20];//用户账号
char mm[20] ;//用户密码
char sjh[20];//注册手机号
};
// 用户列表
struct dz dz[100];
int dznum = 0;
typedef struct {
int id; // ID
int book_id;
char text[200]; // 评论内容
} Comment;
int num_comments = 1;
Comment comments[1000];
void sortMp(){//价格排序
struct book temp;
for(int i = 0; i < num-1; i++) {
for(int j = i+1; j < num; j++) {
if(book[i].price > book[j].price) {
temp = book[i];
book[i] = book[j];
book[j] = temp;
}
}
}
}
void welcome (){//欢迎主页
printf("**********欢迎使用是图书管理系统*************\n");
printf("1.管理身份登录\n");
printf("2.普通用户登录\n");
printf("3.退出\n");
printf("*********************************************\n");
}
//增加图书
void addBook(){
while(1){
printf("输入图书编号\n");
scanf("%s",&book[num].id);
printf("输入图书名称\n");
scanf("%s",&book[num].name);
printf("输入图书状态 1表示图书借阅 2表示未借阅\n");
scanf("%d",&book[num].state);
printf("输入图书价格\n");
scanf("%f",&book[num].price);
printf("输入图书库存量\n");
scanf("%d",&book[num].cl);
printf("是否继续录入y/n \n");
char yn;
scanf(" %c",&yn);
num++;
if(yn=='y'){
continue;
/*continue语句的作用是跳过本次循
环体中余下尚未执行的语句,
立即进行下一次的循环条件判定,
可以理解为仅结束本次循环。
注意:continue语句并没有使整个循环终止。*/
}else{
break;
}
}
}
//显示注册的图书信息
void show(){
//将我们的图书信息显示出来
if(num== 0) {
printf("当前无图书!\n");
return;
} sortMp();
printf("编号\t书名\t 库存量\t 状态\t价格\t评论数\n");
for(int i=0;i<num;i++){
printf("%s\t", book[i].id) ;
printf("%s\t" ,book[i].name) ;
printf("%d\t", book[i].cl) ;
printf("%d\t", book[i].state) ;
printf("%.2f\t",book[i].price) ;
printf("%d\n", book[i].commentcount);
}
}
//修改 信息
void updateBook() {
//处理编号重复问题
//提示修改图书的序号
//输入修改图书的序号之前,可以看到被修改的书
//显示注册的信息
show ();
char a[10];
printf("请输入要修改的图书编号:");
scanf("%s", a);
int i;
for(i = 0; i < num; i++) {
if(strcmp(book[i].id, a) == 0) {
printf("输入修改后的图书编号\n");
scanf("%s",&book[i].id);
printf("请输入修改后的图书名称:");
scanf("%s", book[i].name);
printf("请输入修改后的价格:");
scanf("%f", &book[i].price);
printf("请输入修改后的库存量:");
scanf("%d", &book[i].cl);
printf("修改成功!\n");
return;
}
}
printf("未找到该图书!\n");
}
// 注销图书
void deleteBook() {
char b[10];
printf("请输入要注销的图书编号:");
scanf("%s", b);
int i;
for(i = 0; i < num; i++) {
if(strcmp(book[i].id, b) == 0) {
int j;
for(j = i; j < num - 1; j++) {/*字符串比较函数:strcmp()
格式:strcmp(s1,s2)
功能:比较字符串 s1 和字符串 s2 的大小。
说明
自左至右逐个字符比较字符串中各字符的 ASCII 码
遇到不同字符或'\0'时比较过程结束,此时,ASCII 码值大的字符所在的字符串大*/
book[j] = book[j + 1];
}
num--;
printf("注销成功!\n");
return;
/*函数值及 return
函数值:函数执行后带回的一个结果
函数值通过函数体中 return 返回*/
}
}
printf("未找到该图书!\n");
}
// 借阅图书
void borrowBook() {
char c[10];
printf("请输入要借阅的图书编号:");
scanf("%s", c);
int i;
for (i = 0; i < num; i++) {
if (strcmp(book[i].id, c) == 0) {
if (book[i].cl <= 0) {
printf("该图书已全部借出!\n");
return;
}
book[i].cl--;
book[i].borrow_count++; // 更新借阅次数
printf("借阅成功!\n");
return;
}
}
printf("未找到该图书!\n");
}
// 获取借阅排名前 k 的书籍信息
void get_top_borrowed_books(int k) {
// 按照 borrow_count 从大到小排序
for (int i = 0; i < num - 1; i++) {
for (int j = i + 1; j < num; j++) {
if (book[i].borrow_count < book[j].borrow_count) {
struct book temp = book[i];
book[i] = book[j];
book[j] = temp;
}
}
}
// 输出排名前 k 的书籍信息和借阅次数
printf("借阅排行榜(前 %d):\n", k);
printf("编号\t书名\t借阅次数\n");
for (int i = 0; i < k && i < num; i++) {
printf("%s\t%s\t%d\n", book[i].id, book[i].name, book[i].borrow_count);
}
}
//归还图书
void returnBook() {
char id[10];
printf("请输入要归还的图书编号:");
scanf("%s", id);
int found = 0;
for (int i = 0; i < num; i++) {
if (strcmp(book[i].id, id) == 0) {
found = 1;
if (book[i].state == 2) {
printf("该图书未被借阅,无法归还!\n");
return;
}
int num;
printf("请输入归还数量:");
scanf("%d", &num);
if (num > book[i].borrow_count) { //检查归还数是否合法
printf("归还数量大于借出量!\n");
return;
}
book[i].cl += num;
book[i].borrow_count -= num;
if (book[i].borrow_count == 0) {
book[i].state = 2; // 修改图书状态为未借出
printf("该书已全部归还!\n");
} else {
book[i].state = 1; // 修改图书状态为部分借出
}
printf("还书成功!\n");
}
}
if (!found) {
printf("未找到该图书!\n");
}
}
void add_comment() {// 评论图书
char a[10];
show();
printf("请输入要评论的图书编号:");
scanf("%s", a);
for (int i = 0; i < num; i++) {
if (strcmp(book[i].id, a) == 0) {
int comment_id = num_comments;
comments[num_comments].id = comment_id;
//将评论的编号存储到评论数组 comments 的 id 属性中。
comments[num_comments].book_id = i;
//将评论对应的图书编号存储到评论数组 comments 的 book_id 属性中。
printf("请输入评论:");
getchar(); // getchar()函数可以将之前输入的回车符消耗掉,从而避免对后续输入造成影响。
/*getchar():输入字符数据,格式:getchar()功能:从键盘缓冲区读入一个字符*/
fgets(comments[num_comments].text, sizeof(comments[num_comments].text), stdin);
/*fgets(buffer,n,fp);从 fp 指向的文件读取 n-1 个字符;存储到以 buffer 为首地址的内存空*/
//sizeof(comments[num_comments].text)表示对comments[num_comments].text数组的大小进行了限制,以防止用户输入过长的内容导致内存溢出。
comments[num_comments].text[strlen(comments[num_comments].text)-1] = '\0';
//它从一个评论数组中取出最后一个字符,并将其替换为'\0',以将用户输入的回车符去除。
//strlen(s)的功能是求字符串s的长度
book[i].commentids[book[i].commentcount] = comment_id;//使评论对应书籍
book[i].commentcount++;//使评论数增加
num_comments++;
printf("评论成功!\n");
return;
}
}
printf("没有这本书!\n");
}
// 修改评论
void update_comment() {
char a[10];
show();
printf("请输入要修改评论的图书编号:");
scanf("%s", a);
for (int i = 0; i < num; i++) {
if (strcmp(book[i].id, a) == 0) {
if (book[i].commentcount == 0) {
printf("该图书还没有评论!\n");
return;
}
printf("请输入要修改的评论编号(1-%d):", book[i].commentcount);
int comment_num;
if (scanf("%d", &comment_num) != 1 || comment_num < 1 || comment_num > book[i].commentcount)
//如果用户输入的评论编号无效(不是整数,或者不在有效范围内),则输出无效的评论编号的提示信息,并结束函数。
{
printf("无效的评论编号!\n");
return;
}
int comment_id = book[i].commentids[comment_num-1];
//将用户输入的评论编号转换为评论的编号,存储到变量 comment_id 中。
for (int j = 0; j < num_comments; j++) {
if (comments[j].id == comment_id) {
printf("[%d] %s\n", comments[j].id, comments[j].text);
printf("请输入新的评论:");
getchar(); // 消耗掉之前输入的回车符
fgets(comments[j].text, sizeof(comments[j].text), stdin);
//从标准输入中读取用户输入的新的评论内容,并将其存储到当前评论的 text 属性中。
comments[j].text[strcspn(comments[j].text, "\r\n")] = '\0'; // 去掉末尾可能存在的回车符
printf("修改成功!\n");
return;
}
}
printf("未找到该评论!\n");
return;
}
}
printf("未找到该图书!\n");
}
// 删除评论
void delete_comment() {
char a[10];
show();
printf("请输入要删除评论的图书编号:");
scanf("%s", a);
for (int i = 0; i < num; i++) {
if (strcmp(book[i].id, a) == 0) {
if (book[i].commentcount == 0) {
printf("该图书还没有评论!\n");
return;
}
// 提示用户输入要删除的评论编号,并进行有效性检查
printf("请输入要删除的评论编号(1-%d):", book[i].commentcount);
int comment_num;
scanf("%d", &comment_num);
if (comment_num < 1 || comment_num > book[i].commentcount) {
printf("无效的评论编号!\n");
return;
}
// 通过要删除的评论编号找到对应的评论,然后将其从数组中删除
int comment_id = book[i].commentids[comment_num-1];
for (int j = 1; j < num_comments; j++) {
if (comments[j].id == comment_id) {
for (int k = j; k < num_comments - 1; k++) {
comments[k] = comments[k + 1];// 将数组元素向前移动
}
num_comments--;
for (int k = comment_num-1; k < book[i].commentcount - 1; k++) {
book[i].commentids[k] = book[i].commentids[k+1];
}
book[i].commentcount--;// 更新该图书的评论数目
printf("删除成功!\n");
return;
}
}
}
}
printf("未找到该图书或该图书还没有评论!\n");
}
// 显示图书及评论信息
void show_book_comments() {
char a[10];
show();
printf("请输入要查看评论的图书编号:");
scanf("%s", a);
for (int i = 0; i < num; i++) {
if (strcmp(book[i].id, a) == 0) {
printf("评论数\n");
printf("%d\n", book[i].commentcount);
if (book[i].commentcount > 0) {
printf("评论列表:\n");
//如果当前图书有评论,则使用 for 循环遍历该图书的所有评论,
//并通过 commentids 数组中存储的评论编号找到对应的评论内容,
//输出评论内容和编号。如果当前图书没有评论,则输出提示信息
for (int j = 0; j < book[i].commentcount; j++) {
int comment_id = book[i].commentids[j];
for (int k = 1; k < num_comments; k++) {
if (comments[k].id == comment_id) {
printf("[%d] %s\n", comments[k].id, comments[k].text);
break;
}
}
}
}else {
printf("该图书还没有评论!\n");
}
return;
}
}
printf("没有这本书!\n");
}
//查找书籍
void find_book() {
char b[20];
printf("请输入查找图书的名字:");
scanf("%s", b);
int found = 0;
for (int i = 0; i < num; i++) {
if (strcmp(book[i].name, b) == 0) {
printf("编号:%s\t", book[i].id);
printf("名称:%s\t", book[i].name);
printf("状态:%d\t", book[i].state);
printf("价格:%f\t", book[i].price);
printf("库存量:%d\t", book[i].cl);
printf("\n******查找成功******\n");
found = 1;
}
}
if (found!=1) {
printf("未找到相关图书。\n");
}
}
//注册用户
void zc()
{
printf("请输入编号\n");
scanf("%s",&dz[dznum].usernum ) ;
printf("输入名字\n");
scanf("%s",&dz[dznum].name ) ;
printf("请输入性别\n");
scanf("%s",&dz[dznum].xb );
printf("请输入账号\n");
scanf("%s",&dz[dznum].zh );
printf("请输入密码\n");
scanf("%s",&dz[dznum].mm );
printf("请输入注册手机号\n");
scanf("%s",&dz[dznum].sjh );
dznum++;//变量先使用,然后再自增
printf("注册成功\n") ;
}
//找回密码
void zh()
{
char phone[20];
printf("请输入注册时填写的手机号码:");
scanf("%s", phone);
for (int i = 0; i < dznum; i++)
{
if (strcmp(dz[i]. sjh,phone) == 0)
{
printf("您的账号是:%s\n", dz[i].zh);
printf("账号的密码是: %s\n",dz[i].mm );
return;
}
}
printf("找不到对应的账号!\n");
}
// 登录函数
void dlu() {
char name[20];
char pass[20];
printf("请输入账号:\n");
scanf("%s", &name);
printf("请输入密码:\n");
scanf("%s", &pass);
for (int i = 0; i < dznum; i++) {
if (strcmp(dz[i].zh, name) == 0 && strcmp(dz[i].mm, pass) == 0)
{
printf("登录成功!\n");
while(true){
printf("\n********欢迎用户登录*******\n");
printf("根据序号选择功能\n");
printf("1.借阅图书\n");
printf("2.归还图书\n");
printf("3.图书详情展示\n");
printf("4.图书评论\n");
printf("5.修改评论\n");
printf("6.查看图书评论\n") ;
printf("7.查看借阅排名情况\n");
printf("8.查找图书功能\n") ;
printf("0.返回\n");
printf("***************************\n");
int k;
scanf("%d",&k);
if(k==1){
printf("1.借阅图书\n");
borrowBook();
}else if(k==2){
printf("2.归还图书\n");
returnBook();
}else if(k==3){
printf("3.图书详情展示\n");
show ();
}else if(k==4){
printf("4.图书评论\n");
add_comment();
}else if(k==5){
printf("5.修改评论\n");
update_comment();
}else if(k==6){
printf("6.查看图书评论\n") ;
show_book_comments() ;
}else if(k==7){
printf("7.查看借阅排名情况\n");
int n=10;
get_top_borrowed_books(n);
}else if(k==8){
printf("8.查找图书功能\n") ;
find_book();
}else{
printf("0.返回主页\n");
break;
}
}
return;
}
else
{
printf("登录失败:用户名或密码错误!请重新登录!\n");
return;
}
}
}
void lmenu()//显示登录菜单
{
printf("\n\n\t 欢迎进入登录系统\n\n");
printf("**********************************************");
printf("\n\t\t1.登录系统\n");
printf("\n\t\t2.创建账号\n");
printf("\n\t\t3.找回密码\n");
printf("\n\t\t4.退出系统\n");
printf("\n\t 请按键选择,回车确定\n");
printf("**********************************************");
return ;
}
void comuser()
{
printf("根据序号选择功能\n");
printf("1.借阅图书\n");
printf("2.归还图书\n");
printf("3.图书详情展示\n");
printf("4.图书评论\n");
printf("5.修改评论\n");
printf("6.查看图书评论\n") ;
printf("7.查看借阅排名情况\n");
printf("8.查找图书功能\n") ;
printf("0.返回\n");
}
void mangview()
{
printf("1.查看已存图书\n");
printf("2.注册新图书\n");
printf("3.修改已有图书信息\n");
printf("4.注销现存图书\n");
printf("5.查看图书评论\n") ;
printf("6.管理评论\n");
printf("7.查看借阅排名情况\n");
printf("8.查找图书功能\n") ;
printf("0.返回主页\n");
}
void mauser()
{
printf("根据序号选择功能\n");
printf("1.查看已存图书\n");
printf("2.注册新图书\n");
printf("3.修改已有图书信息\n");
printf("4.注销现存图书\n");
printf("5.查看图书评论\n") ;
printf("6.管理评论\n");
printf("7.查看借阅排名情况\n");
printf("8.查找图书功能\n") ;
printf("0.返回主页\n");
}
int main(){
//程序开始进入欢迎界面
do{
welcome();
printf("选择登录方式的序号,进行登录\n") ;
int xh;
//输入
scanf("%d",&xh);
if(xh==1){//管理员界面
int choice;
char password[20];
printf("\n请输入管理员密码:");
scanf("%s", password);
if(strcmp(password, "1") != 0) { //strcmp字符串比较
printf("\n密码错误!\n");
return 0;
}
do{ //管理员界面
printf("\n********欢迎管理员登录*******\n");
mangview();
printf("*****************************\n");
int mxh;
scanf("%d",&mxh);
if(mxh==1) {
printf("1.查看已存图书\n");
show ();
}else if(mxh==2){
addBook();
}else if(mxh==3){
printf("3.修改已有图书信息\n");
updateBook();
}else if(mxh==4){
printf("4.注销现存图书\n");
deleteBook();
}else if(mxh==5){
printf("5.查看图书评论\n") ;
show_book_comments() ;
}else if(mxh==6){
printf("6.删除图书评论\n");
delete_comment();
}else if(mxh==7){
printf("7.查看借阅排名情况\n");
int k=10;
get_top_borrowed_books(k);
}else if(mxh==8){
printf("8.查找图书功能\n") ;
find_book();
}else{
printf("0.返回主页\n");
break;
}
}while(true);
}
else if(xh==2)
{//用户界面
lmenu();
int xz;
printf("\n输入选择\n");
scanf("%d",&xz);
if(xz==1)
{
dlu();
}
else if(xz==2)
{
zc();
}
else if(xz==3)
{
zh();
}
else if(xz==4)
{
break;
}
}
else{
//输入3,表退出
printf("3.退出,感谢您的使用\n");
exit(0);
break;
}
}while(true);
return 0;
}