Tuesday, 12 June 2018

Chapter 9 // Exercise 7 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


Chapter 9 // Exercise 7


Create an enumerated type for the Book class called Genre. Have the types be fiction, nonfiction, periodical, biography, and children. Give each book a Genre and make appropriate changes to the Book constructor and member functions.

#include "stdafx.h"
#include "std_lib_facilities.h"

enum class Genre
{
 default = 1, fiction, nonfiction, periodical, biography, children
};

class Book
{
public:
 Book();
 ~Book();

 Genre  getGenre() const { return m_genre; }
 string getISBN() const { return m_isbn; }
 string getTitle() const { return m_title; }
 string getAuthor() const { return m_author; }
 int    getDate() const { return m_date; }
 bool   getStatus() const { return m_checkedOut; }

 void setGenre(Genre genre) { m_genre = genre; }
 void setISBN(string num1, string num2, string num3, string char1);
 void setTitle(string title) { m_title = title; }
 void setAuthor(string author) { m_author = author; }
 void setDate(string year);

 void checkBookOut() { m_checkedOut = true; };
 void checkBookIn() { m_checkedOut = false; };

private:
 //m_ prefix to denote member variable
 Genre m_genre;
 string m_isbn, m_title, m_author;
 int m_date;
 bool m_checkedOut;
};

//--OVERLOAD OPERATORS--//

//compare ISBN numbers
bool operator==(const Book& a, const Book& b)
{
 return a.getISBN() == b.getISBN();
}

bool operator!=(const Book& a, const Book& b)
{
 return a.getISBN() != b.getISBN();
}

//print out book
ostream& operator<<(ostream& os, const Book& book)
{
 string genre;
 switch (book.getGenre())
 {
 case Genre::fiction:
  genre = "Fiction";
  break;
 case Genre::nonfiction:
  genre = "Non-Fiction";
  break;
 case Genre::periodical:
  genre = "Periodical";
  break;
 case Genre::biography:
  genre = "Biography";
  break;
 case Genre::children:
  genre = "Children";
  break;
 default:
  genre = "Default";
  break;
 }
 return os << "Title: "      << book.getTitle()  << endl
    << "Author: "     << book.getAuthor() << endl
    << "Genre: "      << genre            << endl
           << "Copyright: "  << book.getDate()   << endl
           << "ISBN: "       << book.getISBN()   << endl
           << "Checked out:" << book.getStatus() << endl
           << endl;
}

//constructor
Book::Book()
{
 m_genre = Genre::default;
 m_isbn = m_title = m_author = "";
 m_date = 0;
 m_checkedOut = false;
}

//deconstructor
Book::~Book() {}

//set the ISBN
void Book::setISBN(string num1, string num2, string num3, string char1)
{
 size_t check;
 //check first number
 check = num1.find_first_not_of("0123456789");
 while (check != string::npos)
 {
  cout << "Not a valid ISBN number, try again: ";
  cin >> num1;
  check = num1.find_first_not_of("0123456789");
 }

 //check second number
 check = num2.find_first_not_of("0123456789");
 while (check != string::npos)
 {
  cout << "Not a valid ISBN number, try again: ";
  cin >> num2;
  check = num2.find_first_not_of("0123456789");
 }

 //check third number
 check = num3.find_first_not_of("0123456789");
 while (check != string::npos)
 {
  cout << "Not a valid ISBN number, try again: ";
  cin >> num3;
  check = num3.find_first_not_of("0123456789");
 }

 //check last character
 check = char1.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXY");
 while (check != string::npos)
 {
  cout << "Not a valid ISBN digit or letter, try again: ";
  cin >> char1;
  check = char1.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXY");
 }

 //set isbn
 m_isbn = "";
 m_isbn.append(num1);
 m_isbn.append("-");
 m_isbn.append(num2);
 m_isbn.append("-");
 m_isbn.append(num3);
 m_isbn.append("-");
 m_isbn.append(char1);
}

//set and check the year of copyright
void Book::setDate(string year)
{
 size_t check;
 check = year.find_first_not_of("0123456789");
 while (check != string::npos || year.size() != 4)
 {
  cout << "Not a valid year try again: ";
  cin >> year;
  check = year.find_first_not_of("0123456789");
 }

 m_date = stoi(year);
}

int main()
{
 Book lotr;
 lotr.setTitle("Lord Of The Rings");
 lotr.setAuthor("J.R.R Tolkien");
 lotr.setGenre(Genre::fiction);
 lotr.setDate("1954");
 lotr.setISBN("1111", "1111", "1111", "J");
 cout << lotr;

 lotr.setISBN("123", "0", "4444", "6");
 lotr.checkBookOut();
 cout << lotr;

 keep_window_open();

 return 0;
}

I don't particularly like using enums, I find them tedious when you need to print out data with them. Pretty much the only way to print out the info as text is via a switch statement which takes up a lot of lines and can harbour bugs if not careful.

No comments:

Post a Comment