Question
Utils.h namespace sdds { // Testing date values for application testing and debugging // these values must not change at submission time. const int sdds_testYear
Utils.h namespace sdds { // Testing date values for application testing and debugging // these values must not change at submission time. const int sdds_testYear = 2023; const int sdds_testMon = 10; const int sdds_testDay = 9; class Utils { bool m_testMode = false; public: // this function will be used to get the current system date or the test date if m_testMode is true void getSystemDate(int* year = nullptr, int* mon = nullptr, int* day = nullptr); // this function will return the number of days in a month based on the year // 1<=mon<=12 year: four digit number (example: 2023) int daysOfMon(int mon, int year)const; // Puts the system date in test mode, where getSystemDate() function will return 2023, 12, 09 // or whatever the three constant test dates are set to void testMode(bool testmode = true); }; extern Utils ut; // provides global access to the ut instance in the Utils.cpp file }
Utils.cpp #define _CRT_SECURE_NO_WARNINGS #include #include #include "Utils.h" using namespace std; namespace sdds { // The ut object of type Utils that is accessible to any file including "Utils.h" to call the Utils // methods Utils ut; void Utils::testMode(bool testmode) { m_testMode = testmode; } void Utils::getSystemDate(int* year, int* mon, int* day) { if (m_testMode) { if(day) *day = sdds_testDay; if(mon) *mon = sdds_testMon; if(year) *year = sdds_testYear; } else { time_t t = std::time(NULL); tm lt = *localtime(&t); if (day) *day = lt.tm_mday; if (mon) *mon = lt.tm_mon + 1; if (year) *year = lt.tm_year + 1900; } } int Utils::daysOfMon(int month, int year)const { int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1 }; int mon = (month >= 1 && month <= 12 ? month : 13)-1; return days[mon] + int((mon == 1) * ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)); } }
The above Utils module is provided with the application. You may add any of your own methods as needed to the Utils class, to be used in the application or add any stand-alone helper functions. (having these functions methods of Utils is preferred)
Recommended methods for Utils
The following are recommended methods that if you develop, it is going to ease the development of the rest of the project since the tasks these functions provide will be needed several times in the project:
void Utils::alocpy(char*& destination, const char* source);
Safely allocates memory in the destination argument and copies the source into it.
- deletes the destination dynamic array and sets it to null
- if the source is not null Allocates memory in the destination to the size of the source and copies the source into it.
int Utils::getint(const char* prompt = nullptr)
If the prompt is not null, it will display it. Then it performs a foolproof entry of an integer. If the user enters an invalid integer it will display "Invalid Integer, retry: " and will not let the user leave the function until a valid integer is entered.
int Utils::getint(int min, int max, const char* prompt=nullptr, const char* errMes=nullptr);
If the prompt is not null it will be displayed before getting a valid integer. (reuse the previous getint()) If the entered integer is not within the acceptable range (min and max) then an error message is displayed and it will not let the user leave the function until an acceptable value is entered. When printing the error message, if the errMes argument is not null it will be displayed followed by ", retry: " otherwise the general error message "Value out of range [min<=val<=max]: " is displayed (replacing min and max with their values)
Note: Implementation of the above functions is optional. You can use your own way to implement the requirements of the application if you like. As we advance through the implementation of the project, more suggestions for Utils function may follow
Milestone 1 Overview
Status Class
A class to keep track of the state of an object by holding the description of the state and an optional status code. For example Error desc: "Invalid Range", Error code: 101
Date Class
A class that encapsulates year, month and day values for date stamping, validation, comparison and date IO purposes.
The Status class
This class encapsulates two values:
- A dynamic C-String for the description of the status of an object.
- An integer for an optional status Code.
Construction
A Status object can be constructed with or without a C-String as a description.
- If the description is provided, a dynamic copy of it will be kept in the class description.
- If the description is not provided, the class description will be set to null.
- In both cases the Code will be zero.
Rule of three
A Status object should be safely copied from or assigned to another Status object and when going out of scope there should be no memory leak.
Assignment operator overloads
A Status object should be able to be assigned to an integer or a C-String. The results of the assignments should set the code or the description dynamically (with no memory leak).
Type Conversion Overloads
- Casting a Status object to an integer should return the code
- Casting a Status object to a constant character pointer should return the description.
- Casting a Status object to a boolean should return true if the description is null and false if it is not. Which means if the Status has no description, the owner class is in a good (true) state. (No news is good news.)
The clear() method
Make a method called clear() that safely deallocates the description and sets the code to zero. This method will return a reference to the current object at the end.
Helper insertion operator overload
Overload the insertion operator to be able to print a Status object using ostream. This operator overload should print the Status only if it is in a bad (false) state. See type conversion(bool overload)
When printing the status object the code is printed only if it is not zero as follows `"ERR#???: " where ??? replaced with the code. Then the description of the Status object is printed.
Status tester output Enter following values : abc 123 -123 12 > abc Container: (Invalid Integer) Error #: 0 Problem: Invalid Integer > 123 Container: (ERR#1: value too high) Error #: 1 Problem: value too high > -123 Container: (ERR#-1: value too low) Error #: -1 Problem: value too low > 12 Container: (12)
The Date Class
Constant values
Make a constant value indicating the largest acceptable value for a year and set it to 2030. (referred as the "maximum year value* here)
Attributes
The date class encapsulates the following:
- Year; an integer between the current year the maximum year value.
- Month; an integer between 1 and 12
- Day; an integer between 1 and the number of days in the month based on the year.
- State; a Status object that holds the validity status of date.
- Formatted; a boolean value that is set to true to print the date as YYYY/MM/DD or false to print it as YYMMDD.
Private Methods
validate
Does not receive any arguments and returns a boolean.
This function validates the year, month and day, kept in the object in the following order (and validation stops if an invalid value is found):
- If the year value is invalid (less than the current year or more than the maximum year value), the State is set to "Invalid year in date" and then set to the code 1.
- If the month value is invalid (less than 1or more than 12), the State is set to "Invalid month in date" and then set to the code 2.
- If the day value is invalid(less than one or more than the maximum number of days in the month based on the year), the State is set to "Invalid day in date" and then set to the code 3.
- The State is cleared if everything is valid.
In the end, if the date is valid the function returns true or false if any of the validations have failed.
unique date value
Make a method to return a unique integer value tied to the date. Use this value to compare two dates. Use the following formula to obtain the unique integer value
year * 372 + mon * 31 + day
Construction
A Date is created either with all three values or no value provided.
- If all three values are provided, the year and month and day will be set to the corresponding values and then they are validated.
- If no initial value is provided, the Date is set to the current system date.
operator overloads for comparison.
Overload all the six comparison operators: ==, !=, <, >, <=, >=
Use the private method, unique date value for the comparison.
state accessor
make an accessor method called state that returns a constant reference to the State of the Date.
formatted modifier
make a modifier method called formatted to set the Formatted flag (attribute) of the Date. This method should return the reference of the current object.
bool conversion overload
If the Date object is casted to a boolean, the state of the date object is returned.
write method
make a method called write that receives and returns a reference of the ostream object in which it inserts the date value as follows:
- If the Formatted attribute is true, it will print the date in the following format: YYYY/MM/DD, month and day are printed in 2 spaces padded with zero.
- If the Formatted attribute is false it will print the date in the following format: YYMMDD, month and day are printed in 2 spaces padded with zero.
read method
make a method called read that receives and returns a reference of the istream object from which it extracts the date value as follows:
The date is entered as one integer value.
- If the value is a four digits integer then the Date is read as: MMDD and the year is set to the current system year.
- If the value is a six digits integer then the date is read as: YYMMDD.
Then the data is validated and if the validation fails the istream object is set to a fail state. istream::setstate(ios::badbit);
Example: 0221 will be read as Year: 2023, Month: 2, Day: 21 240315 will be read as Year: 2024, Month: 3, Day: 15 190101 will be read as Year: 2019, Month: 1, Day 1, which will be an invalid date.
Helper insertion and extraction operator overloads
Overload the insertion and extraction operators to make and read a date object through ostream and istream respectively. (cout and cin)
Date Tester output The first line will change base on the date of execution Current Date: 2023/10/23 Test mode: Current Date formatted (C): 2023/12/09 Current Date unformatted (C): 231209 Future Date formatted (F): 2024/02/03 Future Date unformatted (F): 240203 The current date is NOT the same as the future date The current date is the same as the current date The current date is Less than or equal to the future date The current date is Less than or equal to the current date The current date is Less than the future date The future date is greater than or equal to the current date The future date is greater than or equal to the future date The future date is greater than the current date -------------- Assigning the Current date to the future date! Now both of the dates are the same! Enter the following: 1- abc 2- 12 3- 1212 4- 121212 5- 231312 6- 250229 7- 240229 > abc Invalid date value > 12 ERR#2: Invalid month in date > 1212 Date enterd: 2023/12/12 > 121212 ERR#1: Invalid year in date > 231312 ERR#2: Invalid month in date > 250229 ERR#3: Invalid day in date > 240229 Date enterd: 2024/02/29
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started