Monday, February 26, 2018

Programming Challenge 16.11 - Inheritance Modification

Example Files: InheritanceModification.7z

Notice: The only file that has directly changed is the SearchableVector class. The other files remain the same, and are to be found in the Example Files archive, but are not republished here.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SortableVector.h"

template <class T>
class SearchableVector : public SortableVector<T>
{
    public:
        // Constructors
        SearchableVector() : SortableVector<T>()
        { }

        SearchableVector(int size) : SortableVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);
   
        // Accessor function
        void findItem(const T &);
        int sortAndSearch(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                           SortableVector<T>(obj)
{
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T &
    This function passes the value to search for in a given
    array to the sortAndSearch function. If the value exists,
    it is output. Otherwise a message indicating that the
    value does not exist is output.
   ********************************************************** */

template<class T>
void SearchableVector<T>::findItem(const T &val)
{
    int result = 0;

    result = this->sortAndSearch(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            SearchableVector<T>::sortAndSearch() const T &
    This function first sorts an array, by calling the
    SortableVector class's sortItems() function, then a binary
    search algorithm is used, to find a value in it. If the
    value is found, the position is returned. Otherwise -1 is
    returned.
    ********************************************************** */

template <class T>
int SearchableVector<T>::sortAndSearch(const T &item)
{
    SortableVector<T>::sortItems();
   
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = SimpleVector<T>::getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (SimpleVector<T>::operator[](midPoint) == item)
        {
            position = midPoint;
            status = true;
        }

        SimpleVector<T>::operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                                 firstElem = midPoint + 1;
    }

    return position;
}

#endif

InheritanceMod.cpp


#include "SearchableVector.h"

#include <cstdlib>
#include <ctime>

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SearchableVector<int>    intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    cout << "SORTABLE AND SEARCHABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE + (count * 2);
        doubleTable[count] = rand() % SIZE * (count * 2.2);
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting and searching for values in the arrays:\n\n";
    intTable.findItem(22);
    doubleTable.findItem(132.0);
    charTable.findItem('I');

    cout << "These are the items now in sorted order:\n\n";
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

Example Output:





Programming Challenge 16.10 - SortableVector Class Template

Example Files: SortableVectorClassTemplate.7z

SortableVector.h


#ifndef SORTABLE_VECTOR_H_
#define SORTABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SortableVector : public SimpleVector<T>
{
    public:
        SortableVector() : SimpleVector<T>()
        { }

        SortableVector(int size) : SimpleVector<T>(size)
        { }

        SortableVector(const SortableVector &);

        // Mutator function
        void sortItems();
};

/* **********************************************************
            SortableVector<T>::SortableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SortableVector<T>::SortableVector(const SortableVector &obj) :
                      SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SortableVector<T>::sortItems() : const T &
   This function uses a selection sort algorithm to sort the
    array's elements in ascending order.
   ********************************************************** */

template <class T>
void SortableVector<T>::sortItems()
{
    int startScan = 0;
    int index = 0;
    int minIndex = 0;
    T minValue{};

    for (; startScan < this->getArraySize() - 1; startScan++)
    {
        minIndex = startScan;
        minValue = this->operator[](startScan);

        for (index = startScan + 1; index < this->getArraySize(); index++)
        {
            if (this->operator[](index) < minValue)
            {
                minValue = this->operator[](index);
                minIndex = index;
            }
        }

        this->operator[](minIndex) = this->operator[](startScan);
        this->operator[](startScan) = minValue;
    }
}

#endif

SortableVectorDm.cpp


#include "SortableVector.h"

#include <cstdlib>
#include <ctime>

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SortableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SortableVector<int>    intTable(SIZE);
    SortableVector<double> doubleTable(SIZE);
    SortableVector<char>   charTable(SIZE);

    cout << "SORTABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE * 1 + (4 * 2);
        doubleTable[count] = rand() % SIZE * (count + (4 * 3.44));
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting the items ...\n\n";
    intTable.sortItems();
    doubleTable.sortItems();
    charTable.sortItems();
   
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

ExampleOutput:



Sunday, February 25, 2018

Programming Challenge 16.9 - SearchableVector Modification

Example Files: SearchableVectorModification.7z

Notice: Since no changes have been made to the SimpleVector class, it is included in the Example Files archive, but not republished here. Most of the code for this project is taken from pp. 1020 through 1022 in the 9th Edition, or 1002 through 1004 in the 8th Edition of this book.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SearchableVector : public SimpleVector<T>
{
    public:
        // Constructors
        SearchableVector() : SimpleVector<T>()
        { }

        SearchableVector(int size) : SimpleVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);

        // Accessor function
        int findItem(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                             SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T
    This function uses a binary search algorithm to find an
    item. If the item is found the subscript is returned.
    Otherwise -1 is returned.
   ********************************************************** */

template <class T>
int SearchableVector<T>::findItem(const T &item)
{
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = this->getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (this->operator[](midPoint) == item)
        {
            position = midPoint;
           status = true;
        }
       
        this->operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                        firstElem = midPoint + 1;
    }

    return position;
}

#endif

SearchableVectorMod.cpp


#include "SearchableVector.h"

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;


/* **********************************************************
            findVal() : const <T> &obj, const T &, const string
    This function searches for a value in the object's array.
    If -1 is returned from the findItem() function, a message
    is output to indicate the fact that the value does not
    exist. Otherwise the value and subscript it was found at
    is output.
   ********************************************************** */

template <class T>
void findVal(SearchableVector<T> &obj, const T &val)
{
    int result = 0;

    result = obj.findItem(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                            Function Definition
   ********************************************************** */

void printIntro();
void printOptions(const string *);

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int SIZE = 12;
    int       intVal = 0;
    int       choice = ' ';
    double    doubleVal = 0.0;
    char      charVal = ' ';
   
    const enum   options { INT = 1, DOUBLE = 2, CHAR = 3, PRINT = 4, QUIT = 5 };
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    SearchableVector<int>     intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    printIntro();

    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = ((char)count - 191);  
    }

    do
    {
        printOptions(objNames);
        cout << "Choice: ";
        cin >> choice;

        while (choice < INT || choice > QUIT)
        {
            cout << "Choice: ";
            cin >> choice;
        }
        cout << "\n";

        switch (choice)
        {
            case INT:
            {
                cout << "Enter an integer value to search for: ";
                cin >> intVal;

                findVal(intTable, intVal);
            } break;

            case DOUBLE:
            {
                cout << "Enter an floating-point value to search for: ";
                cin >> doubleVal;

                findVal(doubleTable, doubleVal);
            } break;

            case CHAR:
            {
                cout << "Enter a character to search for: ";
                cin >> charVal;

                findVal(charTable, charVal);
            } break;

            case PRINT:
            {
                print(intTable, objNames[0]);
                print(doubleTable, objNames[1]);
                print(charTable, objNames[2]);
            } break;

            case QUIT:
            {
                cout << "Thank you for trying this program! Have a nice day!";
            } break;
        }
    } while (choice != QUIT);

    cin.get();
    cin.ignore();
   return 0;
}

/* **********************************************************
            printIntro() : const int
    Outputs information about the program's purpose and
    functionality.
   ********************************************************** */

void printIntro()
{
    cout << "SEARCHABLE VECTOR DEMO\n\n";
    cout << "This program let's you search for a value in an integer,\n"
           << "a floating-point, and a character array.\n\n";
    cout << "If the value exists, it will be output to screen. Otherwise\n"
          << "you will see a message telling you that the value does not exist.\n";
    cout << "You can repeat a search as many times as you wish to, or you\n"
          << "can quit the program and try again another time.\n\n";
}

/* **********************************************************
            printOptions() : const string *
    Outputs the available menu options.
   ********************************************************** */

void printOptions(const string *objNames)
{
    cout << "SEARCH TABLE:\n\n";
    cout << "1) " << objNames[0] << "\n";
    cout << "2) " << objNames[1] << "\n";
    cout << "3) " << objNames[2] << "\n";
    cout << "4) " << "Print Values\n";
    cout << "5) Quit\n\n";
}

Example Output:






Saturday, February 24, 2018

Programming Challenge 16.8 - SimpleVector Modification

Example Files: SimpleVectorModification.7z

Notice: Most of the code for this program is taken from chapter 16, pp. 1015 through 1019 in the 9th Edition, or pp. 997 through 1001 in the 8th Edition of this book.

SimpleVector.h


#ifndef SIMPLE_VECTOR_H_
#define SIMPLE_VECTOR_H_

#include <cstdlib>
#include <iostream>
#include <new>

template <class T>
class SimpleVector
{
    private:
        T    *aptr;
        int arraySize;
        int maxCapacity;

        void memError();
        void subError();

        template <class TPrint>
        friend std::ostream &operator << (std::ostream &, const SimpleVector<TPrint> &);

    public:
        SimpleVector();
        SimpleVector(int);
        SimpleVector(const SimpleVector &);
        ~SimpleVector();

        // Mutator functions
        void push_back(const T &);
        void pop_back();

        // Accessor functions
        int getArraySize() const
        { return arraySize; }
       
        T getElementAt(int);   
        T &operator [](const int &);
};

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector()
{
    arraySize = 0;
    maxCapacity = 0;
}

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(int arrSize)
{
    arraySize = arrSize;

    try
    {
        aptr = new T[arrSize];
    }
    catch (std::bad_alloc)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = 0;
    }
}
   
/* **********************************************************
            SimpleVector<T>::SimpleVector() - Copy Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
    arraySize = obj.arraySize;

    aptr = new T[arraySize];

    if (aptr == 0)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = *(obj.aptr + count);
    }
}

/* **********************************************************
            SimpleVector<T>::~SimpleVector() - Destructor
   ********************************************************** */

template <class T>
SimpleVector<T>::~SimpleVector()
{
    if (arraySize > 0)
    {
        delete [] aptr;
    }
}

/* **********************************************************
            SimpleVector<T>::pushBack() : const T, int &
    This function emulates a vector's push_back function. It
    dynamically allocates a temporary array of size n+1, then
    copies the original array's values to it. Next, the last
    element of the new array is assigned the tempVal's value
    before the original array is deleted. Before returning,
    the original array is caused to point to the new array,
    and the arraySize member variable gets incremented.
   ********************************************************** */

template <class T>
void SimpleVector<T>::push_back(const T &tempVal)
{
    T *tempAptr = new T[arraySize + 1];

    for (int count = 0; count < arraySize; count++)
    {
        *(tempAptr + count) = *(aptr + count);
    }
   
    delete[] aptr;
    aptr = tempAptr;
   
    *(aptr + arraySize) = tempVal;

    arraySize++;
}

/* **********************************************************
            SimpleVector<T>::pop_back() : int &
    This function emulates a vector's pop_back function. If
    arraySize is greater 0, the maxCapacity and arraySize will
    get decremented. Next, a temporary array is dynamically
    allocated, to which the original array's values n-1 are
    copied. Then, the original array is deleted, and caused to
    point to the new array. Otherwise, the memError() function
    is called, and the program exits with an error message.
   ********************************************************** */

template <class T>
void SimpleVector<T>::pop_back()
{
    if (arraySize > 0)
    {
        maxCapacity = --arraySize;

        T *tempPtr = new T[maxCapacity];

        for (int count = 0; count < maxCapacity; count++)
        {
            *(tempPtr + count) = *(aptr + count);
        }

        delete[] aptr;
        aptr = tempPtr;
    }
    else
    {
        memError();
    }
}

/* **********************************************************
            T SimpleVector<T>::getElementAt() : int
    This function returns the value stored at the subscript
    in the array.
   ********************************************************** */

template <class T>
T SimpleVector<T>::getElementAt(int subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            T &SimpleVector<T>::operator[]() : const int &
         - Overloaded [] operator
    This function returns a reference to the element in the
    array indexed by the subscript.
   ********************************************************** */

template <class T>
T &SimpleVector<T>::operator[](const int &subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            SimpleVector<T>::subError()
    Displays an error message and terminates the program when
    a subscript is out of range.
    ********************************************************** */

template <class T>
void SimpleVector<T>::subError()
{
    cout << "ERROR: Subscript out of range.\n";
    cin.get();
    cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            SimpleVector<T>::memError()
    Displays an error message and terminates the program when
    memory allocation fails.
   ********************************************************** */

template <class T>
void SimpleVector<T>::memError()
{
    cout << "ERROR: Cannot allocate memory.\n";
    cout << "This program will now exit ...\n";
    std::cin.get();
    std::cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            Overloaded Extraction Operator <<
   ********************************************************** */

template <class T>
std::ostream &operator << (std::ostream &strm, const SimpleVector<T> &obj)
{
    for (int count = 0; count < obj.arraySize; count++)
    {
        strm << (*(obj.aptr + count)) << ' ';
    }

    return strm;
}

#endif

SimpleVectorMod.cpp


#include "SimpleVector.h"

#include <iostream>
using std::cin;
using std::cout;

/* **********************************************************
                            Function Definition
   ********************************************************** */

void printIntro(const int);

int main()
{
    int     SIZE = 10;
    int     count = 0;
    int     intVal = 0;
    double doubleVal = 0;
    char   characterVal = ' ';
    char     choice = ' ';
   
    SimpleVector<int>        intTable(SIZE);
    SimpleVector<double> doubleTable(SIZE);
    SimpleVector<char>   charTable(SIZE);

    printIntro(SIZE);

    cout << "Now filling the arrays with initial values. Please be patient!\n";
    for (; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = count;
    }

    cout << "\nThese are the values currently in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values currently in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values currently in your charTable:\n";
    cout << charTable << "\n\n";

    do
    {
        cout << "Please enter an int value: ";
        cin >> intVal;
        intTable.push_back(intVal);

        cout << "Please enter a floating-point value (Ex: 7.5): ";
        cin >> doubleVal;
        doubleTable.push_back(doubleVal);

        cout << "Please enter a character: ";
        cin >> characterVal;   
        charTable.push_back(characterVal);

        cout << "\nDo you wish to add another set of values (Y/N)? ";
        cin >> choice;
        cout << "\n";

        while (toupper(choice) != 'Y' && toupper(choice) != 'N')
        {
            cout << "\nDo you wish to add another set of values (Y/N)? ";
            cin >> choice;
        }
    } while (toupper(choice) != 'N');

    cout << "These are the values now in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values now your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values now in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "Some values will no be removed from your arrays.\n";
    for (count = intTable.getArraySize(); count > 4; count--)
    {
        intTable.pop_back();
        doubleTable.pop_back();
        charTable.pop_back();
    }

    cout << "\nThese are the new values in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the new values in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the new values in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "This is the end of the Simple Vector demo. Have a nice day!";

    cin.get();
    cin.ignore();
   return 0;
}

/* **********************************************************
            printIntro() : const int
    Outputs information about the program's purpose and
    functionality.
   ********************************************************** */

void printIntro(const int SIZE)
{
    cout << "SIMPLE VECTOR DEMO\n\n";
    cout << "This program emulates functionality in the STL vector class:\n"
           << "   1.] push_back()\n"
          << "   2.] pop_back()\n\n";
    cout << "The program will fill two arrays with an initial set of "
          << SIZE << " values.\n";
    cout << "Then, you are asked to input an integer, a floating-point value,\n"
          << "and a character, which are added to the appropriate array, to\n"
         << "demonstrate how the push_back() function works.\n";
    cout << "Before the program exits, some values will be removed from the\n"
          << "arrays, to demonstrate how the pop_back() function works.\n\n";
}

Example Output:





Thursday, February 22, 2018

Programming Challenge 16.7 - TestScores Class

Example Files: TestScoresClass.7z

TestScores.h


#ifndef TEST_SCORES_H_
#define TEST_SCORES_H_

class TestScores
{
    private:
        int *scorePtr;
        int arraySize;
        int averageScore;

    public:
        // Exception class
        class OutOfRange
        {
            private:
                int errScore;

            public:
                OutOfRange(int subscript)
                {
                    errScore = subscript;
                }

                int getErrSubscript() const
                { return errScore; }
        };

        TestScores(int);
        TestScores(const TestScores &);
        ~TestScores();
   
        // Accessor function
        void calcAverage();

        // Mutator function
        int getAverageScore() const
        { return averageScore; }

        // Overloaded operator functions
        const TestScores operator = (const TestScores &);
        int &operator [](const int &sub);
};

#endif

TestScores.cpp


#include "TestScores.h"

/* **********************************************************
            TestScores::TestScores() - Constructor
    Sets the size of the array and allocates memory for it.
   ********************************************************** */

TestScores::TestScores(int size)
{
    averageScore = 0;

    arraySize = size;
    scorePtr = new int[size];

    for (int count = 0; count < arraySize; count++)
    {
        *(scorePtr + count) = 0;
    }
}

/* **********************************************************
            TestScores::TestScores() - Copy Constructor  
   ********************************************************** */

TestScores::TestScores(const TestScores &obj)
{
    arraySize = obj.arraySize;
    scorePtr = new int[arraySize];

    for (int count = 0; count < arraySize; count++)
    {
        *(scorePtr + count) = *(obj.scorePtr + count);
    }
}

/* **********************************************************
            TestScores::~TestScores() - Destructor
   ********************************************************** */

TestScores::~TestScores()
{
    if (arraySize > 0)
    {
        delete [] scorePtr;
    }
}

/* **********************************************************
            TestScores::operator =() : const obj &
    This function performs a self-assignment check.
   ********************************************************** */

const TestScores TestScores::operator = (const TestScores &right)
{
    if (this != &right)
    {
        delete [] scorePtr;

        arraySize = right.arraySize;
        scorePtr = new int[arraySize];

        for (int count = 0; count < arraySize; count++)
        {
            *(scorePtr + count) = *(right.scorePtr + count);
        }
    }

    return *this;
}

/* **********************************************************
            TestScores::calcAverage()
    This function calculates the average of all test scores.
    If a score is lower 0 or greater 100, the OutOfRange
    exception is thrown. Otherwise the score is accumulated,
    and the average score is calculated, before the function
    exits.
   ********************************************************** */

void TestScores::calcAverage()
{
    int sumTotal = 0;

    for (int count = 0; count < arraySize; count++)
    {
        if (*(scorePtr + count) < 0 || *(scorePtr + count) > 100)
        {
            throw OutOfRange(count);
        }
        else
        {
            sumTotal += *(scorePtr + count);
        }
    }

    averageScore = (sumTotal / arraySize);
}

/* **********************************************************
            TestScores::operator []() : const int &
    Returns a reference to the element in the array indexed by
    the subscript.
   ********************************************************** */

int &TestScores::operator [](const int &sub)
{
    return scorePtr[sub];
}

TestScoresDm.cpp


#include "TestScores.h"

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;

/* **********************************************************
                            Function Definition 
   ********************************************************** */

void evalScores(TestScores &, const int);

int main()
{
    const int SIZE = 5;
    const int NUM_STUDENTS = 3;
    int         score = 0;
   
    const string studentNames[NUM_STUDENTS]{ "M. Hiroshi", "A. Ogawa", "M. Takahata" };

    TestScores scoreArr(SIZE);

    cout << "YAMAGATA 4th JUNIOR HIGH SCHOOL - AVERAGE TEST SCORE CALCULATOR\n\n";

    for (int index = 0; index < NUM_STUDENTS; index++)
    {
        cout << "Student Name: " << studentNames[index] << "\n\n";
        for (int count = 0; count < SIZE; count++)
        {
            cout << "Test-Score #" << (count + 1) << ": ";
            cin >> scoreArr[count];
        }

        evalScores(scoreArr, SIZE);

        cout << "\nThe average score of this student is: "
              << scoreArr.getAverageScore() << "\n";
    }
    cout << "\n";

    cin.ignore();
    cin.get();
    return 0;
}

/* **********************************************************
            evalScores() : obj &, const int
    When the try/catch block in this function executes, the
    object's calcAverage() function is called. If all scores
    are found to be valid, the function exits. Otherwise the
    user is repeatedly asked to input a valid value until one
    is entered. This new value is assigned to the appropriate
    array subscript position.
   ********************************************************** */

void evalScores(TestScores &scoreArr, const int size)
{
    bool tryAgain = true;

    while (tryAgain)
    {
        try
        {
            scoreArr.calcAverage();
            tryAgain = false;
        }
        catch (TestScores::OutOfRange score)
        {
            cout << "\nInvalid Score: " << scoreArr[score.getErrSubscript()] << "\n";
            cout << "Enter a valid score: ";
            cin >> scoreArr[score.getErrSubscript()];
        }
    }
}

Example Output:



Wednesday, February 21, 2018

Programming Challenge 16.6 - IntArray Class Exception

Example Files: IntArrayClassException.7z

Notice: Most of the code is taken from chapter 14, pp. 858 - 863 in the 9th Edition, or pp. 853 through 857 in the 8th Edition of the book. Notice also that there are two versions of the driver program for this programming challenge. One is listed in this solution, the other is contained in the Example Files archive and is called called "IntArrayExceptionSimple.cpp." The last screenshot demonstrates the output of this second driver program.

IntArray.h


#ifndef INT_ARRAY_H_
#define INT_ARRAY_H_

class IntArray
{
    private:
        int *aptr;
        int arraySize;

        void IntArray::subscriptError(const int &);

    public:
        // Exception class - Handles invalid subscripts
        class InvalidSubscript
        {
            private:
                int errSub;

            public:
                InvalidSubscript(const int &errorVal)
                { errSub = errorVal; }

                int getErrSubscript() const
                { return errSub; }
        };

        IntArray(int);
        IntArray(const IntArray &);
        ~IntArray();

        // Accessor function
        int size() const
        { return arraySize; }

        int &operator [](const int &sub);
};

#endif

IntArray.cpp


#include "IntArray.h"

#include <iostream>
using std::cout;

/* **********************************************************
            IntArray::IntArray() - Constructor
    Sets the size of the array and allocates memory for it.
   ********************************************************** */

IntArray::IntArray(int arrSize)
{
    arraySize = arrSize;
    aptr = new int[arrSize];

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = 0;
    }
}

/* **********************************************************
            IntArray::IntArray() - Copy Constructor
   ********************************************************** */

IntArray::IntArray(const IntArray &obj)
{
    arraySize = obj.arraySize;
    aptr = new int[arraySize];

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = *(obj.aptr + count);
    }
}

/* **********************************************************
            IntArray::~IntArray() - Destructor
   ********************************************************** */

IntArray::~IntArray()
{
    if (arraySize > 0)
    {
        delete[] aptr;
    }
}

/* **********************************************************
            IntArray::subscriptError() : const int &
    InvalidSubscript is thrown if the value passed to this
    function is invalid.
   ********************************************************** */

void IntArray::subscriptError(const int &sub)
{
    if (sub < 0 || sub >= arraySize)
    {
        throw InvalidSubscript(sub);
    }
}

/* **********************************************************
            IntArray::operator []() : const int &
    The function makes a call to the subscriptError(). If no
    error is thrown, a reference to the element in the array
    indexed by the subscript is returned.
   ********************************************************** */

int &IntArray::operator [](const int &sub)
{
    subscriptError(sub);

    return aptr[sub];
}

IntArrayException.cpp


#include "IntArray.h"

#include <iostream>
using std::cin;
using std::cout;

/* **********************************************************
                            Function Definitions
   ********************************************************** */

void outputIntro();
void playGame(IntArray &, const int &, const int);
void retrieveValue(IntArray &, const int &, const int);
bool isCorrect(const int &, const int &, const int);

int main()
{
    const int SIZE = 10;
    int         multBy = 0;

    IntArray table(SIZE);

    cout << "MULTIPLICATION GAME\n\n";
    outputIntro();

    cout << "Select a difficulty 1 through " << SIZE << ": ";
    cin >> multBy;

    playGame(table, multBy, SIZE);
    retrieveValue(table, multBy, SIZE);

    cout << "This is the end of the game little Math-Warrior!\n"
          << "You did great! Come and play again!";

    cin.ignore();
    cin.get();
   return 0;
}

/* **********************************************************
            outputIntro()
    Outputs an introduction to the game.
   ********************************************************** */

void outputIntro()
{
    cout << "Welcome, little Math-Warrior! In this game you are about to exercise\n"
          << "your multiplication skills. Enter the multiplication number to hone your\n"
          << "superior skills on. If you enter 2, you have to multiply this number by\n"
          << "1 through 10.\n\n";
    cout << "Example: How much is 2 x 5:\n\n";
    cout << "When you are asked, type in the answer you think is correct. If you make\n"
          << "a mistake, you can retry until the answer is correct. You can do it!\n";
    cout << "Have fun, little Math-Warrior!\n\n";
}

/* **********************************************************
            playGame() : obj &, const int &, const int
    The little Math-Warrior is asked to input the result of a
    multiplication. If the answer is correct, the value is
    copied to the array. Otherwise, he or she is asked to
    enter a valid answer. Once all values are entered, a
    congratulatory message is output and the function exits.
   ********************************************************** */

void playGame(IntArray &table, const int &multBy, const int SIZE)
{
    int result = 0;

    cout << "\nMultiplication-Table: " << multBy << "'s\n\n";
    for (int x = 0; x < SIZE; x++)
    {
        cout << "How much is " << (x + 1) << " x " << multBy << ": ";
        cin >> result;

        while (isCorrect(multBy, result, x + 1) == false)
        {
            cout << "\nTry again, little Math-Warrior!\n";
            cout << (x + 1) << " x " << multBy << " is: ";
            cin >> result;
        }

        if (x == SIZE - 1)
        {
            cout << "\nWELL DONE LITTLE MATH WARRIOR YOU BEAT THIS LEVEL!\n";
        }

        table[x] = result;
    }
}

/* **********************************************************
            isCorrect() : const int &, const int &, const int
    This function validates the correctness of the calculation
    result. If it is, true is returned, otherwise false is
    returned.
   ********************************************************** */

bool isCorrect(const int &multBy, const int &result, const int idx)
{
    bool status = false;

    int calc = multBy * idx;

    if (result == calc)
    {
        cout << "WELL DONE!\n\n";
        status = true;
    }

    return status;
}

/* **********************************************************
            retrieveValue() : obj &, const int, const int &
    This function lets our little Math-Warriors do a review.
    He or she is asked to enter the subscript position of the
    array holding the results. If it is correct, the function
    carries out the calculation and outputs the result. If it
    isn't the try/catch block is executed, until a valid
    subscript position has been provided.
   ********************************************************** */

void retrieveValue(IntArray &table, const int &multBy, const int arrSize)
{
    bool tryAgain = true;
    int  subPosition = 0;

    cout << "TIME FOR A REVIEW!\n\n";
    cout << "Enter a number 1 through 10: ";
    cin >> subPosition;

    while (tryAgain)
    {
        try
        {
            cout << "\nThe result of multiplying "
                  << multBy << " x " << subPosition
                  << " is: " << table[subPosition - 1] << "\n\n";
            tryAgain = false;
        }
        catch (IntArray::InvalidSubscript sub)
        {
            cout << "\nThere was an error, little Math-Warrior!\n"
                  << multBy << " x " << sub.getErrSubscript()+1 << " is invalid.\n";
            cout << "This multiplication table goes from 1 through " << arrSize << "\n";
            cout << "Enter a valid number [1 through " << (arrSize) << "]: ";
            cin >> subPosition;
        }
    }
}

Example Output: 







Programming Challenge 16.5 - Total Template

Example File: TotalTemplate.cpp

Notice: Credit for part of the code and special thanks for so kindly providing it goes to 'Ganado.'

TotalTemplate


#include <iostream>
using std::cin;
using std::cout;

#include <type_traits>
using std::conditional;

#include <typeinfo>
using std::is_same;

template <typename T>
using MyType = typename conditional<is_same<T, unsigned char>::value, int, T>::type;

/* **********************************************************
            template <class T>
    This function lets the user enter a number of values of
    different data types. The only value passed to it is the
    number of values. A running total is kept while the values
    are input, and the total is returned.
   ********************************************************** */

template <class T>
MyType<T> total(int numels)
{
    T value{};
    MyType<T> sumTotal{};
   
    for (; numels > 0; numels--)
    {
        static int count = 1;
   
        cout << "Value #" << count++ << ": ";
        cin >> value;
       
        sumTotal += value;
    }

    return sumTotal;
}

int main()
{
    int numels = 0;

    cout << "TOTAL TEMPLATE DEMO\n\n";
    cout << "This program lets you input any amount of values of\n"
          << "different types of data. For instance int, floating-point\n"
          << "and even characters. Once you finish entering your numbers\n"
          << "or characters, it calculates the total and outputs it.\n\n";

    cout << "Please the number of values you wish to input: ";
    cin >> numels;

    while (numels < 0)
    {
        cout << "Input Error: Enter a valid value!\n";
        cout << "Number of values: ";
        cin >> numels;
    }

    cout << "\nEnter " << numels << " floating-point values\n";
    cout << "\nThe total value is " << total<double>(numels) << "\n\n";

    cout << "Enter " << numels << " integer values\n";
    cout << "\nThe total value is " << total<int>(numels) << "\n\n";

    cout << "Enter " << numels << " characters\n";
    cout << "\nThe total value is " << total<unsigned char>(numels) << "\n\n";

    cout << "Thank you for trying this program! Have a nice day!";

    cin.ignore();
    cin.get();
   return 0;
}

Example Output:



Tuesday, February 20, 2018

Programming Challenge 16.4 - Absolute Value Template

Example File: AbsoluteValue.cpp

AbsoluteValue.cpp


#include <cmath>
using std::abs;

#include <iostream>
using std::cin;
using std::cout;

/* **********************************************************
            template <class T>
    This function returns the absolute value of the parameter
    passed to it.
    ********************************************************** */

template <class T>
T absoluteVal(const T &value)
{
    return abs(value);
}

enum MenuOptions { INT = 'I', DOUBLE = 'D', QUIT = 'Q' };

/* **********************************************************
            Function Definitions  
   ********************************************************** */

void outputOptions();
bool isValidInput(char);
void absoluteDouble();
void absoluteInteger();

int main()
{
    char choice = ' ';

    cout << "ABSOLUTE VALUES\n\n";
    cout << "This program finds the absolute value of a number.\n";
    cout << "Example: The absolute value of |-5.7| is 5.7\n\n";

    do
    {
        outputOptions();
        cin >> choice;
        choice = toupper(choice);
       
        while (isValidInput(choice) == false)
        {
            cout << "Choice: ";
            cin >> choice;
            choice = toupper(choice);
        }           

        switch (choice)
        {       
            case DOUBLE:
            {
                absoluteDouble();
            } break;
           
            case INT:
            {
                absoluteInteger();
            } break;       

            case QUIT:
            {
                cout << "\nThank you for trying this program. Have a nice day!";
            } break;
        }
    } while (choice != QUIT);

    cin.ignore();
    cin.get();
    return 0;
}

/* **********************************************************
            outputOptions()
    Outputs the menu options to screen.
   ********************************************************** */

void outputOptions()
{
    cout << "Do you wish to enter a floating-point or integer value?\n\n"
          << "'D' - Floating-Point Value\n"
          << "'I' - Integer Value\n"
          << "'Q' - Quit Program\n\n";
    cout << "Choice: ";
}

/* **********************************************************
            isValidInput() : char
    Validates the input and returns true if it is, otherwise
    false is returned.
   ********************************************************** */

bool isValidInput(char choice)
{
    if (choice == INT || choice == DOUBLE || choice == QUIT)
    {
        return true;
    }

    return false;
}

/* **********************************************************
            absoluteDouble()
    The user is asked to enter a floating-point value. The
    value is passed to a template function which returns the
    absolute value. The absolute value is output to screen.
   ********************************************************** */

void absoluteDouble()
{
    double floatingPtVal = 0.0;

    cout << "\nEnter a floating-point value: ";
    cin >> floatingPtVal;

    cout << "The absolute value of |" << floatingPtVal << "|"
          << " is: " << absoluteVal(floatingPtVal) << "\n\n";
}

/* **********************************************************
            absoluteInteger()
    The user is asked to enter an integer value. The value is
    passed to a template function which returns the absolute
    value. The absolute value is output to screen.
   ********************************************************** */

void absoluteInteger()
{
    int integerVal = 0;
    cout << "\nEnter an integer value: ";
    cin >> integerVal;

    cout << "The absolute value of |" << integerVal << "|"
          << " is " << absoluteVal(integerVal) << "\n\n";
}

Example Output:



Monday, February 19, 2018

Programming Challenge 16.3 - Minimum/Maximum Templates

Example File: MinimumMaximum.cpp

MinimumMaximum.cpp


#include <iostream>
using std::cin;
using std::cout;

#include <iomanip>
using std::left;
using std::setw;

/* **********************************************************
            template <class Maximum>
    Determines and returns the greater of the two values.
   ********************************************************** */

template <class Maximum>
Maximum greater(const Maximum &valOne, const Maximum &valTwo)
{
    if (valOne > valTwo)
    {
        return valOne;
    }
    else
    {
        return valTwo;
    }
}

/* **********************************************************
            template <class Minimum>
    Determines and returns the smaller of the two values.
   ********************************************************** */

template <class Minimum>
Minimum smaller(const Minimum &valOne, const Minimum &valTwo)
{
    if (valOne < valTwo)
    {
        return valOne;
    }
    else
    {
        return valTwo;
    }
}

void getMaximumVal();
void getMinimumVal();

int main()
{
    char tryAgain = ' ';

    cout << "MINIMUM / MAXIUM\n";
    cout << "Which value is greater, which is less?\n\n";

    do
    {
        getMaximumVal();
        getMinimumVal();

        cout << "Do you wish to try this again? ";
        cin >> tryAgain;

        while (toupper(tryAgain) != 'Y' && toupper(tryAgain) != 'N')
        {
            cout << "Do you wish to try this again? ";
            cin >> tryAgain;
        }
        cout << "\n";
    } while (toupper(tryAgain) != 'N');
   
    cout << "Thank you for trying this program. Have a nice day!\n";

    cin.ignore();
    cin.get();
   return 0;
}

/* **********************************************************
            getMaximumVal()
    Asks the user to enter two floating-point values, and two
    characters. These are passed to the template function and
    compared. The highest values are output to screen.
   ********************************************************** */

void getMaximumVal()
{
    double maxDouble = 0.0;
    double maxDoubleOne = 0.0;
    char   maxChar = ' ';
    char   maxCharOne = ' ';

    cout << "Enter two floating-point values: ";
    cin >> maxDouble >> maxDoubleOne;

    cout << "Enter two characters: ";
    cin >> maxChar >> maxCharOne;

    cout << setw(26) << left << "\nThe greater value is:   "
          << greater(maxDouble, maxDoubleOne) << "\n";

    cout << "The greater character is: "
          << greater(maxChar, maxCharOne) << "\n\n";
}

/* **********************************************************
            getMinimumVal()
    The user is asked to enter two integer values, and two
    characters. The values are passed to the template class
    function to determine the minimum value, which is then
    output to screen.
   ********************************************************** */

void getMinimumVal()
{
    int  minInt = 0;
    int  minIntOne = 0;
    char minChar = ' ';
    char minCharOne = ' ';

    cout << "Enter two integer values: ";
    cin >> minInt >> minIntOne;

    cout << "Enter two characters: ";
    cin >> minChar >> minCharOne;

    cout << setw(25) << left << "\nThe lesser value is: "
          << smaller(minInt, minIntOne) << "\n";

    cout << "The lesser character is: "
          << smaller(minChar, minCharOne) << "\n\n";
}

Example Output: