数据结构和算法——图书馆管理系统(含代码)

目录

一、项目介绍................................ 

二、设计方案及规划.................... 

三、设计内容及步骤.................... 

一、项目介绍

1.课程项目需求分析描述

   1.结合c语言中的相关知识,进行项目课程的设计编译运行。充分调用c语言中,数值、循环、函数、结构体等知识点。

   2.代码编译运行正常,符合 项目要求,系统相关功能可以正常运行。

   3.充分学习和巩固c语言对课程设计的运用。

   4.对于图书管理系统,能够区分出用户与管理员。分别具有的各项功能。图书的新增、修改和删除功能,查看图书的借阅排名和图书的借阅和归还。

   5.对于书籍增加评论,提高用户的使用体验。

2.课程设计目的

  1.充分调动和巩固已学的c语言知识。

  2.更好的,更加灵活的对于数据结构与算法的运用。

  3.增加对于项目的设立和完善,最后取得成功的经验。

  4.提高发现问题,寻找解决方案的综合能力。

3.课程设计要求

  1.项目逻辑思维清晰,页面菜单整洁。

  2.代码编译运行正常。

  3.代码结构严谨,分工明确。

  4.图书管理系统功能项目完善。

4.课程设计意义

让学生能够更好的学习和运用数据结构与算法的知识。加以巩固相关知识,更好的完成好项目。提高学生面对困难,寻找解决方案的能力。发挥承上启下的作用,巩固好已学知识,为以后的课程学习打好基础。提高学生对于系统化使用知识的调用,在完成项目中增加经验,提高编译能力。

二、设计方案及规划

(一)、设计方案

顺应时代的发展潮流,计算机科学的迅猛发展,科技的进步,相关行业越来越在使用电子化发展了。面对图书馆登记借阅和图书信息保存,这些工作需要纸质保存,更新效率不高,对于读者和图书管理员都比较繁琐。

因此决定,使用c语言来设计图书管理系统,更好服务于读者和管理员的工作。结合C语言知识点:变量、数组、结构体、结构体数组、循环、条件判断等,

(二)、设计规划

第一天:

画出相应的流程图,并且完成管理员使图书信息增加,并使图书编号,名称,价格等各种信息的显示功能.

第二天:

完成管理员可以使图书信息的修改,删除,功能.

第三天:

完成用户可以使用,图书单条评论功能,并显示评论,修改单条评论功能.

第四天:

使用户可以多条评论,并且实现可以修改各条评论的功能,并且显示图书的评论数及评论,管理员可以删除评论功能.

第五天:

增加用户的借阅功能,归还功能,并且使图书状态可以随用户借阅和归还而发生改变.

第六天:

增加可以使用图书名称查找功能,调试代码,使之实现以上的各种功能,制作ppt

第七天:

完善代码,进行答辩.

三、设计内容及步骤

设计内容:

  1. 设计管理员和用户页面
  2. 设计管理员的功能
  3. 设计用户的功能

目的:使用c语言对于图书实现智能化,实现管理员的增加、删除和修改等功能,并设计出用户的借阅、归还等功能。提高工作效率,减轻负担。

(包括目的说明和安装配置过程示意图)

安装开发工具dev C++:

1.访问Dev-C++官网.

2.运行安装程序.

3.选择偏好的语言.

4.接受许可协议.

5.选择目标文件夹.

6.选择要安装的组件.

7.创建快捷方式.

8.检查选项并开始安装.

9.等待安装完成.

10.点击完成,退出设置向导.

代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}
        


 

  • 27
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值