手把手教你用 c++ 做 图书管理系统

题目要求

1、问题描述 :
定义图书类,属性有:书名、出版社、ISBN 号、作者、库存量、价格等信息和相关的 对属性做操作的行为。 主要完成对图书的销售、统计和图书的简单管理。
2、功能要求
(1)销售功能:
购买书籍时,输入相应的 ISBN 号,并在书库中查找该书的相关信息。 如果有库存量,输入购买的册数,进行相应计算。如果库存量不够,给出提示信息,结束购 买。
(2)图书简单管理功能:

添加功能:主要完成图书信息的添加,要求 ISBN 号唯一。当添加了重复的编号时,则提示数据添加重复并取消添加。

查询功能:可按书名、ISBN 号、作者、出版社进行查询。若存在相应信息,输出所查 询的信息,若不存在该记录,则提示“该标题不存在!”。

修改功能:可根据查询结果对相应的记录进行修改,修改时注意 ISBN 号的唯一性。

删除功能:主要完成图书信息的删除。输入要删除的 ISBN 号,根据编号删除该物品的 记录,如果该编号不在物品库中,则提示“该编号不存在”。

(3)统计功能。 输出当前书库中所有图书的总数及详细信息;可按书的价格、库存量、作者、出版社进 行统计,输出统计信息时,要按从大到小进行排序。

(4)图书存盘:将当前程序中的图书信息存入文件中。

(5)读出信息:从文件中将图书信息读入程序。

思路分析

图书管理系统肯定要定义“书”类啦~大概有这些属性叭。
在这里插入图片描述
再分析功能要求,大概这个系统是这样
在这里插入图片描述
大致将各个模块分了出来,接下来就开始实现了!

各个模块的实现

“书”类的创建

这个简单,就这几个属性,直接上代码

class Book
{
public:
    Book();
    ~Book();
    string name;
    int ISBN;
    int price;//价格
    string writer;//作者
    string publishingHouse;//出版社
    int inStock; //库存
};

就把他放在Book.h 头文件吧

管理模块的创建及实现

管理权限

定义bool类函数来判断用户输入的密码是否正确,随便写一字符串就好

bool quanxian()
{
    cout << "请输入密码来证明您的权限" << endl;
    string c;
    cin >> c;
    return c == "73748156";
}

添加图书

接下来是添加一本书,先声明一个临时的Book类型变量,然后依次读入他的各个属性,一定要注意判断ISBN号是否唯一
先写一个判断ISBN号是否唯一的函数

int isExist(int isbn, vector<Book>& b)
{
    for (auto& i : b) { 
        //遍历这个Book类vector,判断ISBN是否唯一
        if (i.ISBN == isbn)return -1;
    }
    return 0;
}

然后写添加书籍名称的函数

void addBookName(vector<Book>& b, Book& c) {
    string name;
    cout << "请输入书名" << endl;
    cin >> name;
    c.name = name;
}

添加ISBN的函数,在其中插入判断ISBN是否唯一的函数

void addBookIsbn(vector<Book>& b, Book& c) {
    int isbn;
    cout << "请输入ISBN号" << endl;
    while (true)
    {
        cin >> isbn;
        if (isExist(isbn, b) == -1)cout << "ISBN号重复,请重新输入" << endl;
        else break;
    }
    c.ISBN = isbn;
}

添加作者的函数

void addBookWriter(vector<Book>& b, Book& c) {
    string writer;
    cout << "请输入作者" << endl;
    cin >> writer;
    c.writer = writer;
}

添加出版社的函数

void addBookPublishingHouse(vector<Book>& b, Book& c) {
    string chubanshe;
    cout << "请输入出版社" << endl;
    cin >> chubanshe;
    c.publishingHouse = chubanshe;
}

添加库存的函数

void addBookInStock(vector<Book>& b, Book& c) {
    int kucun;
    cout << "请输入库存" << endl;
    cin >> kucun;
    c.inStock = kucun;
}

添加价格的函数

void addBookPrice(vector<Book>& b, Book& c) {
    int jiage;
    cout << "请输入价格" << endl;
    cin >> jiage;
    c.price = jiage;
}

最后一起调用,做添加图书的总函数

void addBook(vector<Book>& b) {
    Book newbook;//声明一个Book类变量
    addBookName(b, newbook);
    addBookIsbn(b, newbook);
    addBookWriter(b, newbook);
    addBookPublishingHouse(b, newbook);
    addBookInStock(b, newbook);
    addBookPrice(b, newbook);
    //将信息读取到newbook变量中
    b.push_back(newbook);
    //再将newbook添加到Book类vector中
    cout << "添加成功" << endl;
}

这样就可以添加图书了

查找图书

查找图书肯定要按多种条件查找
先做一个菜单

void showMenu4()
{
    cout << "*************************************" << endl;
    cout << "***   请选择您检索书籍的方式   *******" << endl;
    cout << "***   通过书名查找请按1        ******" << endl;
    cout << "***   通过IBSN号查找请按2      ******" << endl;
    cout << "***   通过作者查找请按3        ******" << endl;
    cout << "***   通过出版社查找请按4       ******" << endl;
    cout << "***   退出查找请按0           *******" << endl;
    cout << "***********************************" << endl;
}

理科生整的菜单没有美感。。。。。。。

接下来需要考虑的问题是书籍信息重复问题
书名会重,一个作者会写好多本书,出版社也肯定不会只出一本书
考虑到上述情况,查找结果可能不止一本书

故在查找函数内部再声明一个Book类的vector,
将查到的书存在里边,然后再做第二次确认

还是先做查找书名的函数,参数传两个Book类的vector

void findBookName(vector<Book>& b, vector<Book>& c) {
    string name;
    cout << "请输入您要查找的书籍名称" << endl;
    cin >> name;
    for (auto& i : b) {
        if (i.name == name)
        {
            c.push_back(i);
        }
    }
}

然后是查找作者的函数

void findBookWriter(vector<Book>& b, vector<Book>& c) {
    string writer;
    cout << "请输入您要查找的书籍作者" << endl;
    cin >> writer;
    for (auto& i : b) {
        if (i.writer == writer)
        {
            c.push_back(i);
        }
    }
}

还有查找出版社的函数

void findBookPublishingHouse(vector<Book>& b, vector<Book>& c) {
    string chubanshe;
    cout << "请输入您要查找的书籍出版社" << endl;
    cin >> chubanshe;
    for (auto& i : b) {
        if (i.publishingHouse == chubanshe)
        {
            c.push_back(i);
        }
    }
}

最后是查找ISBN的函数,ISBN肯定是唯一的
所以这种检索方式是最准确的
但是为方便后续操作
依旧传两个vector

void findBookIsbn(vector<Book>& b, vector<Book>& c) {
    cout << "请输入您要查找的书籍ISBN" << endl;
    int ISBN;
    cin >> ISBN;
    for (auto& i : b) {
        if (i.ISBN == ISBN)
        {
            c.push_back(i);
            Book::show(i);
        }
    }
}

查找之后肯定要把图书信息显示出来供使用者确认
做一个展示图书信息的函数
我写到了Book类里

void Book::show(Book b) {
    cout << "书名:" << b.name 
    	 << "\tISBN:" << b.ISBN 
    	 << "\t作者:"<< b.writer 
 	     << "\t出版社:" << b.publishingHouse 
 	     << "\t价格:" << b.price 
  	     << "\t库存:" << b.inStock << endl;
}

最后把这几个查找函数用一个函数封装到一起

Book findBook(vector<Book>& b)
{
    Book tmp;
    vector<Book>c;//为防止书籍其他信息重复,将信息重复的查找结果存在c中
    tmp.ISBN = 0;
    showMenu4();
    char choose2;
    cin >> choose2;
    switch (choose2)
    {

    case '1'://按书名查找
    {
        findBookName(b, c);
        break;
    }
    case '2'://ISBN
    {
        findBookIsbn(b, c);
        break;
    }
    case '3'://作者
    {
        findBookWriter(b, c);
        break;
    }
    case '4'://出版社
    {
        findBookPublishingHouse(b, c);
        break;
    }
    case '0'://退出
    {
        cout << "欢迎下次使用" << endl;
        tmp.ISBN = -1;
        break;
    }
    default: {
        cout << "指令错误,请重新输入" << endl;
        break;
    }
    }
    //开始二次检索
    if (tmp.ISBN != -1)
    {
        if (c.empty())
        //判断找没找到,没找到vector就是空的
        {
            cout << "查无此书" << endl;
            tmp.ISBN = -1;
        }
        else if (c.size() == 1)return c[0];
        //如果vector内只有一个函数,就不再遍历浪费时间啦
        else
        {
            cout << "请确认您要查找的书籍" << endl;
            int i;
            for (i = 0; i < c.size(); ++i) {
            //c里不止一本书,遍历c确认查找的书
                cout << i + 1 << "、\t";
                Book::show(c[i]);
            }
            cout << "请选择您要查找的书籍序号" << endl;
            cin >> i;
            return c[i - 1];
        }
    }
    return tmp;
}

完事,下一个

修改图书

修改图书也简单,跟添加图书差不多吧
无非就是修改单个信息
肯定是要先找到图书,再去修改,
所以函数中传一个vector和一本书就好

先做一个菜单

void showMenu5()
{
    cout << "*************************************" << endl;
    cout << "*****   您想要修改该书哪种信息   ******" << endl;
    cout << "*******    修改书名请按1      *******" << endl;
    cout << "*******    修改ISBN请按2      *******" << endl;
    cout << "*******    修改作者请按3      *******" << endl;
    cout << "*******   修改出版社请按4     *******" << endl;
    cout << "*******    修改价格请按5      *******" << endl;
    cout << "*******    修改库存请按6      *******" << endl;
    cout << "*******    退出修改请按0      *******" << endl;
    cout << "***********************************" << endl;
}

理科生审美标配菜单~

然后还是先做修改单个信息的函数
修改书名的

void modifyBookName(vector<Book>& b, Book& c)
{
    string name;
    cout << "请输入修改后书名" << endl;
    cin >> name;
    int i = 0;
    for (; i < b.size(); ++i) {
        if (b[i].ISBN == c.ISBN)break;
    }
    b[i].name = name;
    cout << "修改成功" << endl;
}

修改ISBN的
这里注意修改后的ISBN不能重复,
调用一次之前写好的函数来判断ISBN是否唯一

void modifyBookIsbn(vector<Book>& b, Book& c)
{
    int isbn;
    cout << "请输入修改后ISBN号" << endl;
    cin >> isbn;
    if (isExist(isbn, b) == -1)//判断ISBN是否重复
    {
        cout << "ISBN重复,修改失败" << endl;
    }
    else {
        int i = 0;
        for (; i < b.size(); ++i) {
            if (b[i].ISBN == c.ISBN)break;
        }
        b[i].ISBN = isbn;
        cout << "修改成功" << endl;
    }
}

修改作者的

void modifyBookWriter(vector<Book>& b, Book& c)
{
    string zuozhe;
    cout << "请输入修改后作者" << endl;
    cin >> zuozhe;
    int i = 0;
    for (; i < b.size(); ++i) {
        if (b[i].ISBN == c.ISBN)break;
    }
    b[i].writer = zuozhe;
    cout << "修改成功" << endl;
}

修改出版社的

void modifyBookChubanshe(vector<Book>& b, Book& c)
{
    string chubanshe;
    cout << "请输入修改后出版社" << endl;
    cin >> chubanshe;
    int i = 0;
    for (; i < b.size(); ++i) {
        if (b[i].ISBN == c.ISBN)break;
    }
    b[i].publishingHouse = chubanshe;
    cout << "修改成功" << endl;
}

修改库存的

void modifyBookKucun(vector<Book>& b, Book& c)
{
    int kucun;
    cout << "请输入修改后库存" << endl;
    cin >> kucun;
    int i = 0;
    for (; i < b.size(); ++i) {
        if (b[i].ISBN == c.ISBN)break;
    }
    b[i].inStock = kucun;
    cout << "修改成功" << endl;
}

修改价格的

void modifyBookJiage(vector<Book>& b, Book& c)
{
    int jiage;
    cout << "请输入修改后价格" << endl;
    cin >> jiage;
    int i = 0;
    for (; i < b.size(); ++i) {
        if (b[i].ISBN == c.ISBN)break;
    }
    b[i].price = jiage;
    cout << "修改成功" << endl;
}

最后封装到一起

void modifyBookInformation(vector<Book>& b, Book& c)
{
    while (true)
    {
        showMenu5();
        char choose5;
        cin >> choose5;
        switch (choose5) {
        case '1':
        {
            modifyBookName(b, c);
            break;
        }
        case '2': {
            modifyBookIsbn(b, c);
            break;
        }
        case '3': {
            modifyBookWriter(b, c);
            break;
        }
        case '4': {
            modifyBookChubanshe(b, c);
            break;
        }
        case '5': {
            modifyBookJiage(b, c);
            break;
        }
        case '6':
        {
            modifyBookKucun(b, c);
            break;
        }
        case '0':
        {
            cout << "退出修改系统" << endl;
            return;
        }
        default:
        {
            cout << "指令错误,请重新输入" << endl;
            break;
        }
        }

    }
}

删除图书

这个更简单了,因为是用的vector来存储书籍
所以删除图书用vector中的erase方法就行

同样也是先查找书籍再删除
参数传一个vector和一本书

我把这个函数写到了Book类中

void Book::deleteBook(vector<Book>& b, Book c)
{
    int i;
    for (i = 0; i < b.size(); i++) {//通过ISBN查找这本书
        if (b[i].ISBN == c.ISBN) {
            b.erase(b.begin() + i);//删除这本书
        }
    }
    cout << "删除成功" << endl;
}

已经完成一半多啦!
在这里插入图片描述

整理模块的封装

做一个修改书目的菜单函数,没什么要求(好看就行)

void showMenu3()
{
    cout << "*************************************" << endl;
    cout << "********   修改该书籍请按1   *****" << endl;
    cout << "********   删除该书籍请按2   *****" << endl;
    cout << "********      退出请按0     *****" << endl;
    cout << "*************************************" << endl;
}

先将修改信息和删除书目两个功能封装到一块,还是用switch结构

void modifyBook(vector<Book>& b, Book& c) {
    showMenu3();
    char choose4;
    cin >> choose4;
    switch (choose4)
    {
        case '0'://退出
        {
            cout << "退出修改系统" << endl;
            break;
        }
        case '1'://修改
        {
            modifyBookInformation(b, c);

            break;
        }
        case '2'://删除
        {
            Book::deleteBook(b, c);
            break;
        }
        default:
        {
            cout << "指令错误,修改失败" << endl;
            break;
        }
    }
}

在做一个整理功能的菜单,将功能选项都写好

void showMenu2()
{
    cout << "*************************************" << endl;
    cout << "********   添加书籍信息请按1      *****" << endl;
    cout << "********   修改书籍信息请按2      *****" << endl;
    cout << "********   退出整理系统请按0      *****" << endl;
    cout << "*************************************" << endl;
}

还是熟悉的风格 ~
然后将整理模块所有功能封装到一个函数中,一样是用switch,大同小异

void arrangeBook(vector<Book>& b) {
    while (true)
    {
        showMenu2();
        char choose3;
        cin >> choose3;
        switch (choose3)
        {
            case'0'://退出
            {
                cout << "退出整理系统" << endl;
                return;
            }
            case '1'://添加
            {
                addBook(b);
                break;
            }
            case '2'://修改
            {
                Book gai = findBook(b);
                if (gai.ISBN != -1)
                {
                    modifyBook(b, gai);
                }
                break;
            }
        }
        system("pause");//按任意键继续
        system("cls");//清屏
    }
}

整理模块的所有功能就都包含在arrangeBook(vector<Book>& b)这个函数中了
在这里插入图片描述

销售模块的创建与实现

销售图书无非就是先检索出来
判断库存,然后输出

直接上代码

void buyBook(vector<Book>& b) {
    Book mai = findBook(b);
    if (mai.ISBN != -1)
    {
        int number;
        cout << "请输入要购买的数量" << endl;
        cin >> number;
        if (number > mai.inStock)//判断库存够不够
        {
            cout << "库存不足,购买失败" << endl;
        }
        else
        {
            int huaxiao = number * mai.price;
            for (int i = 0; i < b.size(); ++i) {
                //遍历找到这本书,并调整他的库存
                if (b[i].ISBN == mai.ISBN)
                {
                    b[i].inStock -= number;
                    break;
                }
            }
            cout << "购买成功" << endl;
            cout << "共花费 " << huaxiao << " 元" << endl;
        }
    }
}

统计模块的创建与实现

统计也就是按ISBN,库存或价格排序输出下,
还是先做个菜单

void showMenu6() {
    cout << "*********************************************" << endl;
    cout << "******    选择你要统计图书信息的排序方式    ******" << endl;
    cout << "*******        按ISBN统计请按1         *******" << endl;
    cout << "*******        按库存统计请按2          *******" << endl;
    cout << "*******        按价格统计请按3          *******" << endl;
    cout << "*******          退出请按0             *******" << endl;
    cout << "*********************************************" << endl;
}

简洁且美观!

因为是用vector存储的书籍
所以排序也是很容易操作
直接用sort方法就可以
故只需要自己定义比较函数

先定义比较ISBN的比较函数

bool isbnCmp(const Book& a, const Book& b)
{
    return a.ISBN > b.ISBN;
}

接着是库存比较函数

bool inStockCmp(const Book& a, const Book& b)
{
    if (a.inStock == b.inStock)return a.ISBN > b.ISBN;
    //库存相等的时候按ISBN排序
    return a.inStock > b.inStock;
}

然后是价格比较函数

bool priceCmp(const Book& a, const Book& b)
{
    if (a.price == b.price)return a.ISBN > b.ISBN;
    //价格相等的时候按ISBN排序
    return a.price > b.price;
}

最后封装好统计函数

void tongji(vector<Book>& b)
{
    showMenu6();
    char choose6;
    cin >> choose6;
    switch (choose6)
    {
    case '0'://退出
    {
        cout << "退出统计系统" << endl;
        return;
    }
    case '1'://isbn
    {
        sort(b.begin(), b.end(), isbnCmp);//排序
        for (const auto& i : b)
        {
            Book::show(i);//显示排完序后的书库
        }
        break;
    }
    case '2'://库存
    {
        sort(b.begin(), b.end(), inStockCmp);
        for (const auto& i : b)
        {
            Book::show(i);
        }
        break;
    }
    case '3'://价格
    {
        sort(b.begin(), b.end(), priceCmp);
        for (const auto& i : b)
        {
            Book::show(i);
        }
        break;
    }
    }
}

文件的读取与存储

用文件流写入或读取文件
记得要加 ftream 的头文件
并且加上宏定义#define FILENAME "library.txt"

open函数要写打开模式

写入模式 ios::out
读取模式 ios::in

具体操作方法如下
保存Book类vector信息代码

void save(vector<Book>& b)
{
    ofstream ofs;
    ofs.open(FILENAME, ios::out);
    for (auto& i : b) {//录入每本书信息
        ofs << i.name << " " << i.ISBN << " " << i.writer << " "
            << i.publishingHouse << " " 
            << i.inStock << " " << i.price << endl;
        //将所有信息存储,信息之间以空格分隔,书之间以换行符分隔
    }
    cout << "保存成功" << endl;
    ofs.close();//关闭文件

}

还有将文件内容读取到Book类vector中
方法是先声明一个Book变量,读取信息后将其插入vector中
代码如下

void fetchBook(vector<Book>& b)
{
    ifstream ifs;
    ifs.open(FILENAME, ios::in);//读文件
    if (!ifs.is_open())//判断是否存在
    {
        cout << "图书文件不存在" << endl;
        ifs.close();
        return;
    }

    Book temp;
    while (ifs >> temp.name && ifs >> temp.ISBN && ifs 
    	>> temp.writer && ifs >> temp.publishingHouse &&
        ifs >> temp.inStock && ifs >> temp.price)//信息读取到temp中
    {
        b.push_back(temp);//将temp存在b中
    }
    ifs.close();
    if (b.empty())
    {
        cout << "图书文件为空" << endl;
    }
    else
        cout << "当前图书种类数目为" << b.size() << "本" << endl;
}

完成!
到这里,题目要求的几个模块就都完成啦~
顺手拓展下再加个用户登录界面完善下吧

创建简易登录界面

有登录肯定得有注册
还是老样子
先做一个巨好看的菜单

void showMenu0() {
    cout << "*************************************" << endl;
    cout << "********  书是人类进步的阶梯  *********" << endl;
    cout << "********    登录帐号请按1    *********" << endl;
    cout << "********    注册账号请按2    *********" << endl;
    cout << "********  退出图书系统请按0  *********" << endl;
    cout << "*************************************" << endl;
}

好看!
在这里插入图片描述

接着先写一个类,就叫User叭

class User {
public:
    User() {}
    ~User() {}
    string userName;
    string password;
};

然后开始写注册函数
当然也要判断用户名是否唯一

判断用户名是否唯一的函数代码

int isUserExist(string name, vector<User>u) {
    for (int i = 0; i < u.size(); ++i) {
        if (u[i].userName == name) return i;
    }
    return -1;
}

接着是注册函数的实现,跟添加图书差不多,
还是先声明一个User类变量,输入各信息后再将其插入到vector中

既然是存储用户信息的vector,当然也要保存在文件中
同样加一个宏定义#define FILENAME2 "users.txt"

然后上代码

void zhuce(vector<User>& u)
{
    string password;
    User tmp;
    string name;
    cout << "请输入用户名" << endl;
    cin >> name;
    int a = isUserExist(name, u);
    if (a == -1)
    {
        tmp.userName = name;
        cout << "请输入密码" << endl;
        cin >> password;
        tmp.password = password;
        u.push_back(tmp);
        ofstream ofs;
        ofs.open(FILENAME2, ios::out);
        for (auto& i : u) {//录入用户信息
            ofs  << i.userName << " "<< i.password << endl;
        }
        cout << "保存成功" << endl;
        ofs.close();//关闭文件
    }
    else cout << "该用户名已被使用,注册失败" << endl;
}

当然不能忘了还有登录的代码没写

bool denglu(vector<User> u)
{
    string name, password;
    cout << "请输入用户名" << endl;
    cin >> name;
    int a = isUserExist(name, u);
    if (a == -1) {
        cout << "用户名不存在,登录失败" << endl;
        return false;
    }
    else
    {
        cout << "请输入密码" << endl;
        cin >> password;
        if (u[a].password == password) {
            cout << "登录成功" << endl;
            return true;
        }
        else
        {
            cout << "密码错误,登录失败" << endl;
            return false;
        }
    }
}

再补一下主函数的封装
在这里插入图片描述

主函数的封装

主函数中声明两个 vector ,再调用两个函数读取本地文件到 vector 中
之后调用 选择函数,来封装所有的模块

int main() {
    vector<Book>lib;
    vector<User>users;
    fetchUser(users);
    fetchBook(lib);
    selectOption(lib, users);
    return 0;
}

主菜单选项的封装

还是先做一个百看不腻的美丽菜单

void showMenu1()
{
    cout << "*************************************" << endl;
    cout << "********  书是人类进步的阶梯  *********" << endl;
    cout << "********    购买书籍请按1    *********" << endl;
    cout << "********    整理书籍请按2    *********" << endl;
    cout << "********  显示书籍信息请按3  *********" << endl;
    cout << "********  保存图书信息请按4  *********" << endl;
    cout << "********  退出图书系统请按0  *********" << endl;
    cout << "*************************************" << endl;
}

觉得好看可以多看一会,我不会不好意思的
在这里插入图片描述
接着是 选择函数,就把所有模块扔到一个 switch 结构里就好啦 ~


```cpp
void selectOption(vector<Book>& b, vector<User>& u)
{
    int h = 0;
    char choose0;
    do {
        showMenu0();
        cin >> choose0;
        switch (choose0)
        {
        case'1'://登录
            if (denglu(u))
            {
                h = 1;
                break;
            }
            else
                continue;
        case'2'://注册
            zhuce(u);
            break;
        case'0':
            cout << "欢迎下次使用" << endl;
            return;
        }
        system("pause");
        system("cls");
    } while ((choose0 != '0' && h != 1));
    while (true)
    {
        //展示主菜单
        showMenu1();
        char choose;
        cin >> choose;
        switch (choose)
        {
        case'1'://购买
        {
            buyBook(b);
            break;
        }
        case'2'://整理
        {
            if (quanxian())
                arrangeBook(b);
            else cout << "密码错误,您没有权限" << endl;
            break;
        }
        case '3'://统计
        {
            if (b.empty())
            {
                cout << "当前无图书" << endl;
                break;
            }
            tongji(b);
            break;
        }
        case '4'://保存
        {
            save(b);
            break;
        }
        case'0'://退出
        {
            cout << "欢迎下次使用" << endl;
            return;
        }
        default:
        {
            cout << "指令错误,请重新输入" << endl;
        }
        }
        system("pause");
        system("cls");
    }
}

在这里插入图片描述
成品上传在这里了

燕大的朋友们可以私信管我要代码哦
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46039856/article/details/106269628