图书管理系统(C++)

图书目录管理系统(C++)

请设计一个简单的图书目录管理系统(初级版)。

图书目录信息包括:

统一书号(不超过13字符)
书名(不超过30字符)
作者(不超过20字符)
出版社(不超过30字符)
出版日期(包括:年、月、日)
价格(精确到分)
注意:为了保证运行窗口能正确地显示,请右击运行窗口,修改“属性”:

在“选项”选项卡中,选中“使用旧版本控制台”
在“字体”选项卡中,选择“8×16”“点阵字体”
在“布局”选项卡中,将屏幕窗口宽度均设为“120”。
具体需求如下:

显示如下的主菜单:
Append Find Remove Modify Show Quit > _
如果用户输入 A 或 a、F 或 f、R 或 r、M 或 m、S 或 s,则可完成相应的操作。如果用户输入其它字符,则显示错误信息。
程序将反复显示主菜单,让用户持续工作。如果用户输入 Q 或 q,则程序结束。

Append Find Remove Modify Show Quit > Q
Thank you! Goodbye!

若用户输入其它字符,则显示错误信息。

Append Find Remove Modify Show Quit > B
Incorrect choice!
Append Find Remove Modify Show Quit > 9
Incorrect choice!
Append Find Remove Modify Show Quit > +
Incorrect choice!

若用户输入 A 或 a,则可以输入新书的信息,将其添加到图书目录中。

Append Find Remove Modify Show Quit > a
     ISBN: 9780439227148
    Title: The Call of the Wild
   Author: Jack London
Publisher: Scholastic Press
 Pub date: 2001/1/1
    Price: 39.4
Append Find Remove Modify Show Quit > A
     ISBN: 9781772262902
    Title: Oliver Twist
   Author: Charles Dickens
Publisher: Engage Books
 Pub date: 2016/9/15
    Price: 648
Append Find Remove Modify Show Quit > a
     ISBN: 9787515911076
    Title: The Call of the Wild
   Author: Jack London
Publisher: Aerospace Publishing House
 Pub date: 2016/5/1
    Price: 29.8

若用户输入的日期信息不正确,则显示错误信息,并要求用户重新输入。

Append Find Remove Modify Show Quit > A
     ISBN: 9787501592401
    Title: The Old Man and the Sea
   Author: Ernest Hemingway
Publisher: Knowledge Press
 Pub date: 2016/2/30
Incorrect date! Please reenter: 2016/6/31
Incorrect date! Please reenter: 2016/8/1
    Price: 25.8

若用户输入 S 或 s,则按书号升序排序,然后列表显示全部图书。

Append Find Remove Modify Show Quit > S
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9780439227148 The Call of the Wild           Jack London          Scholastic Press               2001/01/01    39.40
9781772262902 Oliver Twist                   Charles Dickens      Engage Books                   2016/09/15   648.00
9787501592401 The Old Man and the Sea        Ernest Hemingway     Knowledge Press                2016/08/01    25.80
9787515911076 The Call of the Wild           Jack London          Aerospace Publishing House     2016/05/01    29.80

若用户输入 F 或 f,则输入书名,然后显示该书名的图书。如果没有对应的图书,则显示错误信息。

Append Find Remove Modify Show Quit > F
Title: The Call of the Wild
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9780439227148 The Call of the Wild           Jack London          Scholastic Press               2001/01/01    39.40
9787515911076 The Call of the Wild           Jack London          Aerospace Publishing House     2016/05/01    29.80
Append Find Remove Modify Show Quit > f
Title: Gulliver's Travels
Not found!

说明:输出查找结果时,不作排序操作。

若用户输入 R 或 r,则输入书号,然后将删除该书号的图书。如果没有对应的图书,则显示错误信息。

Append Find Remove Modify Show Quit > r
ISBN: 9781772262902
Remove(y/n)? n
Append Find Remove Modify Show Quit > S
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9780439227148 The Call of the Wild           Jack London          Scholastic Press               2001/01/01    39.40
9781772262902 Oliver Twist                   Charles Dickens      Engage Books                   2016/09/15   648.00
9787501592401 The Old Man and the Sea        Ernest Hemingway     Knowledge Press                2016/08/01    25.80
9787515911076 The Call of the Wild           Jack London          Aerospace Publishing House     2016/05/01    29.80
Append Find Remove Modify Show Quit > R
ISBN: 9780439227148
Remove(y/n)? Y
Append Find Remove Modify Show Quit > s
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9781772262902 Oliver Twist                   Charles Dickens      Engage Books                   2016/09/15   648.00
9787501592401 The Old Man and the Sea        Ernest Hemingway     Knowledge Press                2016/08/01    25.80
9787515911076 The Call of the Wild           Jack London          Aerospace Publishing House     2016/05/01    29.80
Append Find Remove Modify Show Quit > r
ISBN: 9787515914145
Not found!
Append Find Remove Modify Show Quit > s
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9781772262902 Oliver Twist                   Charles Dickens      Engage Books                   2016/09/15   648.00
9787501592401 The Old Man and the Sea        Ernest Hemingway     Knowledge Press                2016/08/01    25.80
9787515911076 The Call of the Wild           Jack London          Aerospace Publishing House     2016/05/01    29.80

要求:用户回答是否删除时,必须回答 Y 或 N (大小写均可)。如果是其它字符,则显示错误信息,要求用户重新回答。

Append Find Remove Modify Show Quit > R
ISBN: 9781772262902
Remove(y/n)? k
Incorrect answer!
Remove(y/n)? $
Incorrect answer!
Remove(y/n)? N

若用户输入 M 或 m,则可以修改图书信息。首先按书号查找,然后重新输入该图书的信息。

Append Find Remove Modify Show Quit > m
ISBN: 9787515911076
Modify(y/n)? y
     ISBN: 9787544724968
    Title: The House on Mango Street
   Author: Sandra Heathneros
Publisher: Yilin Press
 Pub date: 2012/1/1
    Price: 30
Append Find Remove Modify Show Quit > M
ISBN: 9787501592401
Modify(y/n)? n
Append Find Remove Modify Show Quit > m
ISBN: 9787515914145
Not found!
Append Find Remove Modify Show Quit > S
ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---
9781772262902 Oliver Twist                   Charles Dickens      Engage Books                   2016/09/15   648.00
9787501592401 The Old Man and the Sea        Ernest Hemingway     Knowledge Press                2016/08/01    25.80
9787544724968 The House on Mango Street      Sandra Heathneros    Yilin Press                    2012/01/01    30.00

要求:用户回答是否修改时,必须回答 Y 或 N (大小写均可)。如果是其它字符,则显示错误信息,要求用户重新回答。

Append Find Remove Modify Show Quit > M
ISBN: 9787544724968
Modify(y/n)? K
Incorrect answer!
Modify(y/n)? *
Incorrect answer!
Modify(y/n)? n

相关习题:图书目录管理系统(高级版)。

Append Find Remove Modify Show Quit > Thank you! Goodbye!
q

提交代码

/*
请设计一个简单的图书目录管理系统。

图书目录信息包括:

统一书号(不超过13字符)
书名(不超过30字符)
作者(不超过20字符)
出版社(不超过30字符)
出版日期(包括:年、月、日)
价格(精确到分)

*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<iomanip>

using namespace std;
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cctype>

// String 类
class STRING
{
public:
    friend istream& operator >> (istream& cin, STRING& str);   // 输入,输出运算符的重载
    friend ostream& operator << (ostream& cout, STRING& str);

    STRING() : len(0), str(new char[1]) { str[0] = '\0'; }  // STRING 类的构造函数,通过成员初始化表给成员赋值 可以减少一些不不要的操作 提高效率 最开始
                                                            // 就开辟一个单位的空间然后用来存放 '\0'表示什么都没有就可以了
    STRING(const char* str);    //拷贝构造函数
    STRING(int len, char sym);  // 拷贝构造函数的重载
    STRING& operator = (const STRING& str);   // 赋值
    ~STRING() { delete[] str; }

    friend bool operator > (const STRING& str1, const STRING& str2);  // 比较函数
    friend bool operator < (const STRING& str1, const STRING& str2);
    friend bool operator >= (const STRING& str1, const STRING& str2);
    friend bool operator <= (const STRING& str1, const STRING& str2);
    friend bool operator == (const STRING& str1, const STRING& str2);
    friend bool operator != (const STRING& str1, const STRING& str2);

    void Input();
    void Output() { printf("%s", str); }

    int Length() { return len; }

    void Set(const char* str);
    const char* Get();

protected:
    int len;
    char* str;
};

istream& operator >> (istream& cin, STRING& str)  // 输入
{
    cin.getline(str.str, 10000);
    return cin;
}
ostream& operator << (ostream& cout, STRING& str) // 输出
{
    cout << str.str;
    return cout;
}


STRING::STRING(const char* str) :	// 拷贝构造
    len(strlen(str)), str(new char[len + 1])  // 利用成员初始化表来把新的str的信息复制过来
{
    strcpy(this->str, str);		// 字符串复制函数
}

STRING::STRING(int len, char sym) :		// 拷贝构造重载 作用是将STRING初始化为 len 个 sym字符
    len(len), str(new char[len + 1])
{
    int k;
    for (k = 0; k < len; k++)
    {
        str[k] = sym;
    }
    str[k] = '\0';  // 这一步末尾加'\0'
}

STRING& STRING::operator = (const STRING& str)  // 赋值
{
    this->len = strlen(str.str);
    delete[] this->str;
    this->str = new char[str.len + 1];
    strcpy(this->str, str.str);
    return *this;
}

// 一堆比较函数
bool operator > (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) > 0;
}
bool operator < (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) < 0;
}
bool operator >= (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) >= 0;
}
bool operator <= (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) <= 0;
}

bool operator == (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) == 0;
}
bool operator != (const STRING& str1, const STRING& str2)
{
    return strcmp(str1.str, str2.str) != 0;
}

void STRING::Set(const char* str)    // 通过set函数对STRING类的私有成员进行操作
{
    len = strlen(str);				 // 这里要先确定输入的字符串的长度
    delete[] this->str;				 // 然后销毁原来的字符串
    this->str = new char[len + 1];   // 重新开辟一段空间 这个空间的大小是len + 1 因为字符串末尾还有个'\0'
    strcpy(this->str, str);			 // 动用strcpy 函数将输入的str拷贝过来 
}

const char* STRING::Get()		    // 获取成员str的函数
{
    return str;
}

void STRING::Input()			    // 字符串的输入函数
{
    char* str = new char[10000];
    cin.getline(str, 10000);	    // 注意这个函数的书写方式 c++的编译器里面有一些是不支持gets的所以一般用cin.getline()

    len = strlen(str);			    // 这些都是小细节 将原来的内存释放 不仅节约内存 还防止内存泄漏
    delete[] this->str;
    this->str = new char[len + 1];
    strcpy(this->str, str);
}

// 不同类的分割线 上面是STREING类
/// //
// 下面是日期类

class MYDATE    // 日期类
{
public:
    // 加号与减号的重载
    friend MYDATE operator + (const MYDATE& date, const int day2); // 日期对象 + 天数
    friend MYDATE operator - (const MYDATE& date, const int day2); // 日期对象 - 天数
    friend int operator-(const MYDATE& date, const MYDATE& other); // 日期对象 - 日期对象

    // -= += 运算符重载
    MYDATE& operator+=(const int day2);
    MYDATE& operator-=(const int day2);

    // 前置 ++ -- 运算符的重载
    MYDATE& operator++();
    MYDATE& operator--();

    // 后置 ++ -- 运算符的重载
    MYDATE operator++(int);
    MYDATE operator--(int);

    // 关系运算符的重载
    friend bool operator >(const MYDATE& data1, const MYDATE& data2);
    friend bool operator >=(const MYDATE& data1, const MYDATE& data2);
    friend bool operator <(const MYDATE& data1, const MYDATE& data2);
    friend bool operator <=(const MYDATE& data1, const MYDATE& data2);
    friend bool operator ==(const MYDATE& data1, const MYDATE& data2);
    friend bool operator !=(const MYDATE& data1, const MYDATE& data2);

    // 类型转换运算符重载
    operator int() const;

    // 时间的输入输出
    friend istream& operator>>(istream& cin, MYDATE& time);  // 输入
    friend ostream& operator<<(ostream& cout, const MYDATE& time);  // 输出

    // 日期类定义以下符号常量
    static int const daysPer400Years = 146097;
    static int const daysPer100Years = 36524;
    static int const daysPer4Years = 1461;
    static int const daysPerYear = 365;
    static int const monthsPerYear = 12;
    static int const daysPerWeek = 7;
    static int const daysPerMonth[12];
    static char const weekName[7][10];

    // 逻辑控制变量
    static bool flag;
    // 构造函数和析构函数
    MYDATE(int year = 1, int month = 1, int day = 1) // 构造
    {
        // cout << "Create ";
        if (IsValid(year, month, day))
        {
            this->year = year;
            this->month = month;
            this->day = day;
        }
        else
        {
            this->year = 1;
            this->month = 1;
            this->day = 1;
        }
        // cout << *this << '\n';
    }

    ~MYDATE() // 析构
    {
        // cout << "Destroy ";
        // cout << *this << '\n';
    }

    // 时间的拷贝和赋值
    MYDATE(const MYDATE& time);   // 拷贝
    MYDATE& operator = (const MYDATE& time);  // 赋值

    // Judge leap year
    static bool IsLeapYear(int year);

    // 计算闰年的天数
    static int NumLeapYear(int year);

    // 判断月份是否有效
    static bool IsValidMonth(int month);
    static bool IsValid(int year, int month, int day);

    // 求月份最大数
    static int MaxDayMonth(int year, int month);

    // 求一年的天数
    int NumDayYear() const;

    // 求全部年数的总天数
    int TotalDay() const;

    // 时间转换成日期
    void TotalDay(int day);

    // 求当前星期
    int DayWeek() const;

    // 逻辑开关
    static void FlagOn();
    static void FlagOff();

    // 设置函数
    void Set(int year, int month = 1, int day = 1);

    // 获取函数
    int Year() const;  // 年份的获取
    int Month() const; // 月份的获取
    int Day() const;   // 当前天数的获取
    void Get(int& year, int& month, int& day) const;  // 全部的获取
private:
    int year, month, day;
};

// 逻辑变量
bool MYDATE::flag = false;

// 数组必须在类外初始化
int const MYDATE::daysPerMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char const MYDATE::weekName[7][10] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };

// 时间的拷贝和赋值
MYDATE::MYDATE(const MYDATE& time)   // 拷贝
{
    // cout << "Clone ";
    this->year = time.year;
    this->month = time.month;
    this->day = time.day;
    // cout << *this << endl;
}
MYDATE& MYDATE::operator = (const MYDATE& time)  // 赋值
{
    // cout << "Assign ";
    this->year = time.year;
    this->month = time.month;
    this->day = time.day;
    // cout << *this << endl;
    return *this;
}

// Judge leap year
bool MYDATE::IsLeapYear(int year)
{
    if ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)))
    {
        return true;
    }
    else
    {
        return false;
    }
}

// 计算闰年的天数
int MYDATE::NumLeapYear(int year)
{
    return year / 4 + year / 400 - year / 100;
}

// 判断月份是否有效
bool MYDATE::IsValidMonth(int month)
{
    return 0 < month && month < 13 ? true : false;
}

// 求月份最大数
int MYDATE::MaxDayMonth(int year, int month)
{
    int temp;
    if (year >= 0 && MYDATE::IsValidMonth(month))
    {
        if (MYDATE::IsLeapYear(year))
        {
            if (month == 2)
            {
                temp = MYDATE::daysPerMonth[1] + 1;
            }
            else
            {
                temp = MYDATE::daysPerMonth[month - 1];
            }
        }
        else
        {
            temp = MYDATE::daysPerMonth[month - 1];
        }
    }
    else
    {
        temp = 0;
    }
    return temp;
}

bool MYDATE::IsValid(int year, int month, int day)
{
    int flag = 0;
    if (year > 0 && MYDATE::IsValidMonth(month))
    {
        if (IsLeapYear(year))
        {
            if (month == 2)
            {
                flag = 1 <= day && day <= 29;
            }
            else
            {
                flag = 1 <= day && day <= MYDATE::daysPerMonth[month - 1];
            }
        }
        else
        {
            flag = 1 <= day && day <= MYDATE::daysPerMonth[month - 1];
        }
    }
    else
    {
        flag = 0;
    }
    return flag;
}

// 时间的输入,输出

istream& operator >> (istream& cin, MYDATE& date)  // 输入
{
    char sym;
    int year, month, day;
    cin >> year >> sym >> month >> sym >> day;
    while ((!MYDATE::IsValid(year, month, day)))
    {
        cout << "Incorrect date! Please reenter: ";
        cin >> year >> sym >> month >> sym >> day;
    }
    date.year = year;
    date.month = month;
    date.day = day;
    return cin;
}
ostream& operator<<(ostream& cout, const MYDATE& date) // 输出
{
    return cout << right << setfill('0') << setw(4) << date.year << '/' << setw(2) << date.month << '/' << setw(2) << date.day << setfill(' ');
}


// 求天数
int MYDATE::NumDayYear() const
{
    int temp = this->month - 1;
    int sum = 0;
    for (int i = 0; i < temp; ++i)
    {
        if (i == 1)
        {
            if (IsLeapYear(this->year))
            {
                sum += MYDATE::daysPerMonth[i] + 1;
            }
            else
            {
                sum += MYDATE::daysPerMonth[i];
            }
        }
        else
        {
            sum += MYDATE::daysPerMonth[i];
        }
    }
    return sum + this->day;
}


void MYDATE::TotalDay(int days)
{
    if (days > 0)
    {
        int daysLeft;
        int years, months;
        years = 1 + (days / daysPer400Years) * 400 + (days % daysPer400Years / daysPer100Years) * 100 + (days % daysPer400Years % daysPer100Years / daysPer4Years) * 4 + (days % daysPer400Years % daysPer100Years % daysPer4Years / daysPerYear);
        daysLeft = days % daysPer400Years % daysPer100Years % daysPer4Years % daysPerYear;
        if (daysLeft == 0)
        {
            year = years - 1;
            month = 12;
            day = 31;
            if (TotalDay() > days)
            {
                day--;
            }
        }
        else
        {
            year = years;
            int i = 0;
            for (months = 1; months <= 12; months++)
            {
                i += MaxDayMonth(years, months);
                if (daysLeft <= i)
                {
                    month = months;
                    day = daysLeft - (i - MaxDayMonth(years, months));
                    break;
                }
            }
        }
    }
}

// 求最开始到现在的总天数
int MYDATE::TotalDay() const
{
    int temp = this->year - 1;
    int leap = NumLeapYear(temp);
    int sum = leap * 366 + (temp - leap) * 365;
    sum += this->NumDayYear();
    return sum;
}

// 求当前星期
int MYDATE::DayWeek() const
{
    int d = this->TotalDay() % 7;
    return d;
}

// 逻辑开关
void MYDATE::FlagOn()
{
    MYDATE::flag = true;
}
void MYDATE::FlagOff()
{
    MYDATE::flag = false;
}

// 设置函数
void MYDATE::Set(int year, int month, int day)
{
    if (IsValid(year, month, day))
    {
        this->year = year;
        this->month = month;
        this->day = day;
    }
}

// 获取函数
int MYDATE::Year() const // 年份的获取
{
    return year;
}
int MYDATE::Month() const// 月份的获取
{
    return month;
}
int MYDATE::Day()  const // 当前天数的获取
{
    return day;
}
void MYDATE::Get(int& year, int& month, int& day) const
{
    year = this->year;
    month = this->month;
    day = this->day;
}

// 加号与减号的重载  // 全局函数作友元不需要作用域运算符
MYDATE operator+(const MYDATE& date, const int day2) // 日期对象 + 天数
{
    int total = date.TotalDay() + day2;
    MYDATE x;
    x.TotalDay(total);
    return x;
}

MYDATE operator-(const MYDATE& date, const int day2) // 日期对象 - 天数
{
    int total = date.TotalDay() - day2;
    MYDATE x;
    x.TotalDay(total);
    return x;
}

int operator-(const MYDATE& date, const MYDATE& other) // 日期对象 - 日期对象
{
    return date.TotalDay() - other.TotalDay();
}

// += -= 运算符重载
MYDATE& MYDATE::operator+=(const int day2)
{
    this->TotalDay(this->TotalDay() + day2);
    return *this;
}
MYDATE& MYDATE::operator-=(const int day2)
{
    this->TotalDay(this->TotalDay() - day2);
    return *this;
}

// 前置++ -- 运算符重载
MYDATE& MYDATE::operator++()
{
    int temp = this->TotalDay() + 1;
    this->TotalDay(temp);
    return *this;
}
MYDATE& MYDATE::operator--()
{
    int temp = this->TotalDay() - 1;
    this->TotalDay(temp);
    return *this;
}

// 后置 ++ -- 运算符的重载
MYDATE MYDATE::operator++(int)
{
    int total = this->TotalDay() + 1;
    MYDATE t(*this);
    this->TotalDay(total);
    return t;
}
MYDATE MYDATE::operator--(int)
{
    int total = this->TotalDay() - 1;
    MYDATE t(*this);
    this->TotalDay(total);
    return t;
}

// 关系运算符的重载
bool operator >(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() > data2.TotalDay())
    {
        return true;
    }
    return false;
}
bool operator >=(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() >= data2.TotalDay())
    {
        return true;
    }
    return false;
}
bool operator <(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() < data2.TotalDay())
    {
        return true;
    }
    return false;
}
bool operator <=(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() <= data2.TotalDay())
    {
        return true;
    }
    return false;
}
bool operator ==(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() == data2.TotalDay())
    {
        return true;
    }
    return false;
}
bool operator !=(const MYDATE& data1, const MYDATE& data2)
{
    if (data1.TotalDay() != data2.TotalDay())
    {
        return true;
    }
    return false;
}

// 类型转换运算符重载
MYDATE::operator int() const
{
    return this->year;
}

// 不同类的分割线 上面是日期类
/// //
// 下面是书本类

typedef struct _NODE_
{
    STRING num;
    STRING title;
    STRING auth;
    STRING pub;
    MYDATE B_date;
    double price;
    struct _NODE_* next;
}B_NODE;

class Book_Lib
{
public:
    Book_Lib();
    ~Book_Lib();
    void Book_Catalogue();   // 书本的目录
    void Book_Append();   // 选项 A 插入一本书
    void Book_Traverse(); // 选项 S 对图书的遍历
    void Book_Find(STRING& title);  // 选项 F 图书的查找
    void Book_Remove(STRING& num); // 选项 R 图书的删除
    void Book_Modify(STRING& num);  // 选项 M 图书的修改
    void BooK_Title_Insertion_Sort();  // 按照书名的递增的插入排序法
private:
    int length;
    B_NODE* B_head;
};

void Book_Lib::Book_Catalogue()   // 书本的目录
{
    cout << "ISBN--------- Title------------------------- Author-------------- Publisher--------------------- Pub-date-- Price---\n";
}
Book_Lib::Book_Lib() :length(0), B_head(new B_NODE)  // 先初始化
{
    B_head->next = NULL;        // 带头结点的链表
}
Book_Lib::~Book_Lib()  // 析构函数释放结点内存
{
    B_NODE* s;
    while (this->B_head->next)
    {
        s = this->B_head->next;
        this->B_head->next = s->next;
        free(s);
    }
    this->length = 0;
    this->B_head->next = NULL;
}

void Book_Lib::Book_Append()   // 选项 A 插入一本书
{
    B_NODE* book, * p = B_head;
    book = new B_NODE;
    cout << right;
    cout << setw(11) << "ISBN: ";
    book->num.Input();

    cout << setw(11) << "Title: ";
    book->title.Input();

    cout << setw(11) << "Author: ";
    book->auth.Input();

    cout << setw(11) << "Publisher: ";
    book->pub.Input();

    cout << setw(11) << "Pub date: ";
    cin >> book->B_date;

    cout << setw(11) << "Price: ";
    cin >> book->price;

    this->length++;
    while (p->next)  // 尾插法插入一个结点
    {
        p = p->next;
    }
    p->next = book;
    book->next = NULL;
}

void Book_Lib::BooK_Title_Insertion_Sort()
{
    B_NODE* h, * p, * q, * s;
    h = this->B_head->next;
    this->B_head->next = NULL;

    while (h)
    {
        s = h;
        h = s->next;

        p = this->B_head;
        q = p->next;
        while (q && (s->title > q->title))
        {
            p = q;
            q = p->next;
        }
        p->next = s;
        s->next = q;
    }
}

void Book_Lib::Book_Traverse() // 选项 S 对图书的遍历
{
    for (B_NODE* it = this->B_head->next; it != NULL; it = it->next)
    {
        cout << left
            << setw(13) << it->num << ' '
            << setw(30) << it->title << ' '
            << setw(20) << it->auth << ' '
            << setw(30) << it->pub << ' ';
        cout << it->B_date;
        printf("%9.2f\n", it->price);
    }
}

void Book_Lib::Book_Find(STRING& title)  // 选项 F 图书的查找
{
    int flag = 0;
    for (B_NODE* it = this->B_head->next; it != NULL; it = it->next)
    {
        if (title == it->title)
        {
            if (flag == 0)
            {
                this->Book_Catalogue();
            }
            cout << left
                << setw(13) << it->num << ' '
                << setw(30) << it->title << ' '
                << setw(20) << it->auth << ' '
                << setw(30) << it->pub << ' ';
            cout << it->B_date;
            printf("%9.2f\n", it->price);
            flag = 1;
        }
    }
    if (flag == 0)
    {
        cout << "Not found!\n";
    }
}

void Book_Lib::Book_Remove(STRING& num) // 选项 R 图书的删除
{
    int flag = 0;
    char choice;
    B_NODE* s = this->B_head;   // s 相当于 it的前驱
    B_NODE* it = s->next;
    for (; it != NULL; it = it->next)
    {
        if (it->num == num)  // 先找到书号的迭代器
        {
            flag = 1;
            cout << "Delete(y/n)? ";
            cin >> choice;
            choice = toupper(choice);
            while (!(choice == 'Y' || choice == 'N'))
            {
                cout << "Incorrect answer!\n";
                cout << "Delete(y/n)? ";
                cin >> choice;
                choice = toupper(choice);
            }
            if (choice == 'Y')  // 如果是Y的话就删除这个迭代器对应的元素
            {
                s->next = it->next;
                free(it);
            }
            break;  // 然后退出循环
        }
        else
        {
            s = it;
        }
    }
    if (flag == 0)  // 没有书号的情况
    {
        cout << "Not found!\n";
    }
}

void Book_Lib::Book_Modify(STRING& num)  // 选项 M 图书的修改
{
    int flag = 0;
    char choice;

    for (B_NODE* it = this->B_head->next; it != NULL; it = it->next)  // 通过迭代器对图书管理系统进行修改
    {
        if (it->num == num)
        {
            flag = 1;
            cout << "Modify(y/n)? ";
            cin >> choice;
            choice = toupper(choice);
            while (!(choice == 'Y' || choice == 'N'))
            {
                cout << "Incorrect answer!\n";
                cout << "Modify(y/n)? ";
                cin >> choice;
                choice = toupper(choice);
            }
            if (choice == 'Y')
            {
                cin.get();
                cout << right;
                cout << setw(11) << "ISBN: ";
                it->num.Input();

                cout << setw(11) << "Title: ";
                it->title.Input();

                cout << setw(11) << "Author: ";
                it->auth.Input();

                cout << setw(11) << "Publisher: ";
                it->pub.Input();

                cout << setw(11) << "Pub date: ";
                cin >> it->B_date;

                cout << setw(11) << "Price: ";
                cin >> it->price;
            }
            break;
        }
    }
    if (flag == 0)
    {
        cout << "Not found!\n";
    }
}

int main()
{
    char choice;
    Book_Lib bkl;
    STRING num;
    STRING title;
    do
    {
        cout << "Append Find Remove Modify Show Quit > ";
        cin >> choice;
        cin.get();
        choice = toupper(choice);
        switch (choice)
        {
        case 'A':
            bkl.Book_Append();
            break;
        case 'S':
            bkl.BooK_Title_Insertion_Sort();
            bkl.Book_Catalogue();
            bkl.Book_Traverse();
            break;
        case 'F':
            cout << "Title: ";
            title.Input();
            bkl.Book_Find(title);
            break;

        case 'R':
            cout << "ISBN: ";
            num.Input();
            bkl.Book_Remove(num);
            break;

        case 'M':
            cout << "ISBN: ";
            num.Input();
            bkl.Book_Modify(num);
            break;

        case 'Q':
            break;
        default:
            cout << "Incorrect choice!\n";
            break;
        }
    } while (choice != 'Q');

    return 0;
}

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值