Friday, 8 June 2018

Chapter 9 // Exercise 5 - 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 5



This exercise and the next few require you to design and implement a Book class, such as you can imagine as part of software for a library. Class Book should have members for the ISBN, title, author, and copyright date. Also store data on whether or not the book is checked out. Create functions for returning those data values. Create functions for checking a book in and out. Do simple validation of data entered into a Book; for example, accept ISBNs only if the form n-n-n-x where n is an integer and x is a digit or letter. Store an ISBN as a string.


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

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

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

 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; };

 void printStats();

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

//constructor
Book::Book()
{
 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);
}

//print book details
void Book::printStats()
{
 cout << "Title: " << m_title << endl;
 cout << "Author: " << m_author << endl;
 cout << "Copyright: " << m_date << endl;
 cout << "ISBN: " << m_isbn << endl;
 if (m_checkedOut)
  cout << "Checked out: Yes" << endl;
 else
  cout << "Checked out: No" << endl;

 cout << endl;
}


int main()
{
 Book lotr;
 lotr.setTitle("Lord Of The Rings");
 lotr.setAuthor("J.R.R Tolkien");
 lotr.setDate("1954");
 lotr.setISBN("1111", "1111", "1111", "J");
 lotr.printStats();

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

 keep_window_open();

 return 0;
}


This was quite a confusing task as many assumptions had to be made. First, what kind of copyright date should be set? Generally the day and month are optional, so I decided to only accept the year of copyright. Second, how many integers could be allowed for the ISBN format? I'm not sure if he meant only 1 number or however many. For example 1-1-1-H, or 11111-45676543-4-7. I decided to go with the latter.

The hardest part was the check for the ISBN, however whilst searching how to solve turning a string into an int, I came across a method of std::string called 'find_first_not_of' which handily takes in a string of letters that you want included and then returns the position of the first letter not wanted. This made checking the ISBN parts easy, as the while is set to check if there is a position or not. If there is one, then an undesired character was entered, if there is no position then there were no unwanted characters. A very handy method.

No comments:

Post a Comment