Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Before starting with part 1, we will introduce two functions These two member functions are available in istream: setstate(); peek(); setstate() manually sets the status

Before starting with part 1, we will introduce two functions

These two member functions are available in istream:

setstate(); peek();

  • setstate() manually sets the status of the istream object to the desired state. In our case we will be calling setstate as follows to manually set any object of istream (like cin) to a fail state:

// Examples: // assuming there is a funciton called readData as follows istream& readData(istream& istr){ type variable{}; istr >> variable; if(/*logic for variable being invalid*/){ istr.setstate(ios::failbit); // this manually sets istr to failure // if the variable is readable but not acceptable } return istr; } // Or: int getAge(){ int age{}; cin >> age; if(age < 19){ cin.setstate(ios::failbit); // this sets cin to fail if the age is bellow 19 } return age; } void someLogic(){ cout << "Enter your name: "; int age = getAge(); if(cin.fail()){ cout << "You are not old enough to consume alcoholic drinks in Ontario!" <

  • peek() it peeks and checks the next character without extracting it from the keyboard. With this function, you can check and see what is the next character before reading it. setting m_name to nullptr before constructor invocation

// Example char next; int value; cout <<"Enter a number: "; next = cin.peek(); if(next < '0' || next >'9'){ // checking if the next character in keyboard is not a digit cout << "You did not enter a number!"; } else{ cin >> value; } cin.ignore(1000, ' '); // flush the invalid value or everything after the number.

Part 1 - lab (50%), The HealthCard class

Your task for this part of your workshop is to complete the implementation of a class called HeathCard. This class encapsulates some basic health-card information of a person in Ontario using the following attributes:

class HealthCard { char* m_name{}; long long m_number; char m_vCode[3]; char m_sNumber[10]; public: ... };

  • m_name to hold the full name of a person which is Dynamically allocated
  • m_number to hold the main health card number
  • m_vCode Version code of the card
  • m_sNumber Stock Control Number

Validation

These values are validated (considered valid) as follows:

  • Full name is a Cstring that is not null and not empty.
  • The main health number consists of 10 digits (>999999999 and <9999999999)
  • The version number consists of two characters
  • The Stock control number consists of nine characters

The HeathCard class is to validate and store the above information via initialization and data entry from istream.

Also, the HeathCard class must comply with the rule of three. (i.e. the implementation of copy constructor, copy assignment and destructor)

Although the name of the HealthCard is dynamically held, we can assume that the maximum length for a name is 55 characters. This value should be kept in a constant global variable so it can be changed at compile-time if needed.

 const int MaxNameLength = 55; 

Finally, A HeathCard object should reveal its status (of being valid or invalid) via a Boolean type conversion overload (a true outcome means the object is valid and a false outcome means it is invalid).

To accomplish the above and have an organized and modular code, implement these private methods to help you with the implementation of the whole logic: (you can add more if you like to)

Private Methodsbool validID(const char* name, long long number, const char vCode[] , const char sNumber[]) const;

Returns true is the four parts of the ID card are valid. (see Validation)

void setEmpty();

Sets the HeathCard object to a recognizable empty (invalid) state by setting m_name to nullptr;

void allocateAndCopy(const char* name);

  • Free the memory pointed by m_name
  • Allocate enough memory to store name Cstring
  • Copy the Cstring pointed by name into the newly allocated memory pointed by m_name

void HealthCard::extractChar(istream& istr, char ch) const;

"peek()" and see if the next character in the keyboard buffer is the same as the ch argument

  • If it is the same, Remove it from the keyboard and throw it away! (i.e. istr.ignore())
  • If not:
    • Ignore all the remaining characters (up to 1000 characters) or the value of ch (use istr.ignore(int n,char c))
    • Set the istream into a fail state (use istr.setstate(iso::failbit))

ostream& printIDInfo(ostream& ostr)const;

Inserts the three parts related to the main card number, version code and stock number of the health card information into the istr object in the following format:

1234567890-AB, XY7652341

and then returns the istr object reference

void set(const char* name, long long number, const char vCode[], const char sNumber[]);

Validates the arguments, reallocates memory for the name and sets the object attributes to their corresponding values.

  • If the name and the three parts are valid (see Validation) call the private function to validate
    • Calls the reallocateAndCopy function to set the name
    • Sets the three parts to their values (m_number, m_vCode, m_sNumber)
  • If not, it deletes the memory pointed by m_name and sets the object to a safe empty state (setEmpty())

Constructors

The HeathCard can either get created with no values (default constructor) into a safe empty state or use all four values.

Instead of overloading the constructor you can use one constructor with the default values for the four parameters, (i.e nullptr, 0, {}, {} ) and remember to reuse the set function for the latter case.

Note that since the m_name attribute is initialized in the class definition to be nullptr, there is no need to worry about setting it to nullptr before calling the set function.

Rule of threeCopy Constructor

HeathCard(const HeathCard& hc);

  • if the hc object is valid it will set the values of the current object to those of the incoming argument (hc using assignment to *this).

Copy Assignment operator overload

HeathCard& operator=(const HeathCard& hc);

  • First, it will make sure that this is not a "self-copy" by comparing the address of the current object and the address of the incoming argument.
    • If it is not a self copy this function works exactly like the copy constructor
  • If it is a self copy don't perform any action At the end return the reference of the current object.

Destructor

deletes the memory pointed by m_name.

Boolean type conversion operator

Returns true if m_name is not nullptr, else it will return false

ostream& print(ostream& ostr, bool toFile = true) const;

If the current object is in a valid state it inserts the values of the card information in two different formats based on the value of the toFile argument:

  • if toFile is true, prints the data in a comma-separated format:
    • prints the name
    • print comma
    • print the health card ID information using the private function printIDInfo
  • if toFile is false prints the data in the following format:
    • In 50 characters, left-justified and padded with dots ('.'): prints the name
    • print the health card ID information using the private function printIDInfo
  • At the end, it returns the ostr reference

istream& read(istream& istr);

Reads the Contact information in following format:

  • name
  • comma
  • main health number
  • dash
  • version number characters
  • comma
  • stock control number

Example: Luke Skywalker,1231231234-XL,AF1234567

implementation

  • define local variables for the four parts.
  • using istream::get() read the name up to MaxNameLength or a comma (do not extract comma)
  • extract a comma using extractChar private function
  • extract the main health number into a local variable (istr >> m_number;)
  • extract a dash '-' using extractChar private function
  • extract the version number code into a vCode local variable using get for 3 char or up to ',' whichever comes first
  • extract a comma ',' using extractChar private function
  • extract the stock control number to the local variable (using get to read 10 char or up to ' ' whichever comes first)
  • extract a new line character ' ' (using extractChar private function)
  • if istr is not in a failure state
    • all data were read successfully, use the set private function to set values of the object to read value
  • before returning, clear the state using istr.clear() and ignore the remaining of the line until ' '
  • at the end return the istr reference

insertion operator overload

ostream& operator<<(ostream& ostr, const Contact& hc);

if hc is valid it will print it using the print function on the screen and not on File, (i.e. onFile is false). Otherwise, it will print "Invalid Card Number".

In the end, it will return the ostr reference.

extraction operator overload

istream& operator>>(istream& istr, Contact& hc)

returns the read method of the hc argument.

The tester program

// Workshop #6: // Version: 1.0 // File name: main.cpp // Date: 2021/12/02 // Author: Wail Mardini // Description: // This file tests the lab section of your workshop /////////////////////////////////////////////////// #include  #include  #include "HealthCard.h" using namespace std; using namespace sdds; int noOfRecs(const char* filename); void showFile(const char* filename); HealthCard ReadCardFromFile(istream& istr); void dataEntryTest(); void validationTest(); int main() { int i; int recs = noOfRecs("HealthCardInfo.csv"); HealthCard C{ "Gandalf The Grey",111,"XL","123234LA"}; ifstream CardFile("HealthCardInfo.csv"); ofstream goodCardFile("goodInfo.csv"); validationTest(); dataEntryTest(); for (i = 0; i < recs; i++) { C = ReadCardFromFile(CardFile); cout << C << endl; if (CardFile) C.print(goodCardFile, true); } if (i == recs) cout << " All records were read successfully!" << endl; else { cout << "Read " << i - 1 << " out of " << recs << " Records successfully" << endl; cout << "Record number " << i << " is invalid!" << endl; } showFile("goodInfo.csv"); return 0; } void validationTest() { int i; HealthCard C[]{ {"Fred Soley", 1234567890,"AB","WQ1234567"}, {nullptr, 1234567890,"AB","WQ1234567" }, {"Fred Soley", 123456789,"B","WQ1234567" }, {"Fred Soley", 1234567890,"AB","WQ123456" }, {"Fred Soley", 1234567890,"AB","WQ1234567" }, {"Fred Soley", 234567890,"AB","Q1234567" }, {"Fred Soley", 234567890,"B","WQ1234567" }, {"Fred Soley", 1234567890,"B","Q1234567" }, }; cout << "Validation Test" << endl; for (i = 0; i < 8; cout << C[i++] << endl); } int noOfRecs(const char* filename) { int num = 0; ifstream file(filename); while (file) num += (file.get() == ' '); return num; } void showFile(const char* filename) { ifstream file(filename); char ch; cout << "Contents of " << filename << endl << "----------------------------------------------------------------" << endl; while (file.get(ch)) { cout << ch; } } void dataEntryTest() { HealthCard C{ "Fred Soley", 1234567890,"AB","WQ123456" }; cout << endl << "Data entry test." << endl; cout << "Enter the test data using copy and paste to save time:" << endl << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-XL,AF123456" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-L,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,131231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name 1231231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; } HealthCard ReadCardFromFile(istream& istr) { HealthCard C; istr >> C; return C; }

Tester output

Validation Test Fred Soley........................................1234567890-AB, WQ1234567 Invalid Health Card Record Invalid Health Card Record Invalid Health Card Record Fred Soley........................................1234567890-AB, WQ1234567 Invalid Health Card Record Invalid Health Card Record Invalid Health Card Record Data entry test. Enter the test data using copy and paste to save time: Enter the following: >Person Name,1231231234-XL,AF1234567 >Person Name,1231231234-XL,AF1234567 HealthCard Content: Person Name.......................................1231231234-XL, AF1234567 Enter the following: >Person Name,1231231234-XL,AF123456 >Person Name,1231231234-XL,AF123456 HealthCard Content: Invalid Health Card Record Enter the following: >Person Name,1231231234-L,AF1234567 >Person Name,1231231234-L,AF1234567 HealthCard Content: Invalid Health Card Record Enter the following: >Person Name,1231231234-,AF1234567 >Person Name,1231231234-,AF1234567 HealthCard Content: Invalid Health Card Record Enter the following: >Person Name,131231234-XL,AF1234567 >Person Name,131231234-XL,AF1234567 HealthCard Content: Invalid Health Card Record Enter the following: >Person Name 1231231234-XL,AF1234567 >Person Name 1231231234-XL,AF1234567 HealthCard Content: Invalid Health Card Record Invalid Health Card Record 2Person Name2.....................................1231231234-XL, AF1234567 Invalid Health Card Record 4Person Name3.....................................1231231234-XL, AF1234567 Invalid Health Card Record Invalid Health Card Record Invalid Health Card Record 8Person Name7.....................................1231231234-XL, AF1234567 Invalid Health Card Record Invalid Health Card Record 11Person Name10...................................1231231234-XL, AF1234567 12Person Name11...................................1231231234-XL, AF1234567 13Person Name12...................................1231231234-XL, AF1234567 14Person Name13...................................1231231234-XL, AF1234567 15Person Name.....................................1231231234-XL, AF1234567 Invalid Health Card Record 17Person Name.....................................1231231234-XL, AF1234567 18Person Name.....................................1231231234-XL, AF1234567 Invalid Health Card Record 20P...............................................1231231234-XL, AF1234567 21Person Name.....................................1231231234-XL, AF1234567 22Person Name.....................................1231231234-XL, AF1234567 Invalid Health Card Record 24Person Name.....................................1231231234-XL, AF1234567 25Person Name.....................................1231231234-XL, AF1234567 All records were read successfully! Contents of goodInfo.csv ---------------------------------------------------------------- 2Person Name2,1231231234-XL, AF1234567 4Person Name3,1231231234-XL, AF1234567 8Person Name7,1231231234-XL, AF1234567 11Person Name10,1231231234-XL, AF1234567 12Person Name11,1231231234-XL, AF1234567 13Person Name12,1231231234-XL, AF1234567 14Person Name13,1231231234-XL, AF1234567 15Person Name,1231231234-XL, AF1234567 17Person Name,1231231234-XL, AF1234567 18Person Name,1231231234-XL, AF1234567 20P,1231231234-XL, AF1234567 21Person Name,1231231234-XL, AF1234567 22Person Name,1231231234-XL, AF1234567 24Person Name,1231231234-XL, AF1234567 25Person Name,1231231234-XL, AF1234567 

Files to Submit

HealthCard.h HealthCard.cpp main.cpp HealthCardInfo.csv

HealthCard.cpp

#define _CRT_SECURE_NO_WARNINGS #include  #include "HealthCard.h" using namespace std; namespace sdds { }

HealthCard.h

#ifndef SDDS_HEALTHCARD_H #define SDDS_HEALTHCARD_H namespace sdds { const int MaxNameLength = 55; class HealthCard { char* m_name{}; long long m_number; char m_vCode[3]; char m_sNumber[10]; public: }; } #endif // !SDDS_HealthCard_H

HealthCardInfo.csv

1Person Name1Person Name1Person Name1Person Name1Person Name1Person Name1Person Name1,1231231234-XL,AF1234567 2Person Name2, 1231231234-XL,AF1234567 , 1231231234-XL,AF1234567 4Person Name3,1231231234-XL,AF1234567 5Person Name4,1231231234-,AF1234567 6Person Name5,123123234-XL,AF1234567 7Person Name6,-XL,AF134567 8Person Name7,1231231234-XL,AF1234567 9Person Name8,1231231234-,AF1234567 10Person Name9,1231231234-XL,AF123456 11Person Name10,1231231234-XL,AF1234567 12Person Name11,1231231234-XL,AF1234567 13Person Name12,1231231234-XL,AF1234567 14Person Name13,1231231234-XL,AF1234567 15Person Name,1231231234-XL,AF1234567 16Person Name,1231231234-XL,AF234567 17Person Name,1231231234-XL,AF1234567 18Person Name, 1231231234-XL,AF1234567 19Person Name,123121234-XL,AF1234567 20P,1231231234-XL,AF1234567 21Person Name,1231231234-XL,AF1234567 22Person Name,1231231234-XL,AF1234567 23Person Name,1231231234-L,AF1234567 24Person Name,1231231234-XL,AF1234567 25Person Name,1231231234-XL,AF1234567

main.cpp

// Workshop #6: // Version: 1.0 // File name: main.cpp // Date: 2021/12/02 // Author: Wail Mardini // Description: // This file tests the lab section of your workshop /////////////////////////////////////////////////// #include  #include  #include "HealthCard.h" using namespace std; using namespace sdds; int noOfRecs(const char* filename); void showFile(const char* filename); HealthCard ReadCardFromFile(istream& istr); void dataEntryTest(); void validationTest(); int main() { int i; int recs = noOfRecs("HealthCardInfo.csv"); HealthCard C{ "Gandalf The Grey",111,"XL","123234LA"}; ifstream CardFile("HealthCardInfo.csv"); ofstream goodCardFile("goodInfo.csv"); validationTest(); dataEntryTest(); for (i = 0; i < recs; i++) { C = ReadCardFromFile(CardFile); cout << C << endl; if (CardFile) C.print(goodCardFile, true); } if (i == recs) cout << " All records were read successfully!" << endl; else { cout << "Read " << i - 1 << " out of " << recs << " Records successfully" << endl; cout << "Record number " << i << " is invalid!" << endl; } showFile("goodInfo.csv"); return 0; } void validationTest() { int i; HealthCard C[]{ {"Fred Soley", 1234567890,"AB","WQ1234567"}, {nullptr, 1234567890,"AB","WQ1234567" }, {"Fred Soley", 123456789,"B","WQ1234567" }, {"Fred Soley", 1234567890,"AB","WQ123456" }, {"Fred Soley", 1234567890,"AB","WQ1234567" }, {"Fred Soley", 234567890,"AB","Q1234567" }, {"Fred Soley", 234567890,"B","WQ1234567" }, {"Fred Soley", 1234567890,"B","Q1234567" }, }; cout << "Validation Test" << endl; for (i = 0; i < 8; cout << C[i++] << endl); } int noOfRecs(const char* filename) { int num = 0; ifstream file(filename); while (file) num += (file.get() == ' '); return num; } void showFile(const char* filename) { ifstream file(filename); char ch; cout << "Contents of " << filename << endl << "----------------------------------------------------------------" << endl; while (file.get(ch)) { cout << ch; } } void dataEntryTest() { HealthCard C{ "Fred Soley", 1234567890,"AB","WQ123456" }; cout << endl << "Data entry test." << endl; cout << "Enter the test data using copy and paste to save time:" << endl << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-XL,AF123456" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-L,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,1231231234-,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name,131231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; cout << "Enter the following:" << endl << ">Person Name 1231231234-XL,AF1234567" << endl << ">"; cin >> C; cout << "HealthCard Content:" << endl << C << endl; } HealthCard ReadCardFromFile(istream& istr) { HealthCard C; istr >> C; return C; } 

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Introduction to Wireless and Mobile Systems

Authors: Dharma P. Agrawal, Qing An Zeng

4th edition

1305087135, 978-1305087132, 9781305259621, 1305259629, 9781305537910 , 978-130508713

More Books

Students also viewed these Programming questions

Question

List four common types of finite elements?

Answered: 1 week ago