Skip to content

Instantly share code, notes, and snippets.

@DragonOsman
Last active December 21, 2021 16:51
Show Gist options
  • Select an option

  • Save DragonOsman/c372f99863d52db4b3dabf427ded6b8c to your computer and use it in GitHub Desktop.

Select an option

Save DragonOsman/c372f99863d52db4b3dabf427ded6b8c to your computer and use it in GitHub Desktop.
// Osman Zakir
// 12 / 21 / 2021
// Beginning C++20: From Novice to Professional by Ivor Horton and Peter Van Weert
// Chapter 8 Exercise 1
// Exercise Specs:
/**
* Write a function, validate_input(), that accepts two integer arguments that
* represent the upper and lower limits for an integer that is to be entered.
* It should accept a third argument that is a string describing the input,
* with the string being used in the prompt for input to be entered. The
* function should prompt for input of the value within the range specified by
* the first two arguments and include the string identifying the type of value to
* be entered. The function should check the input and continue to prompt for input
* until the value entered by the user is valid. Use the validate_input() function
* in a program that obtains a user’s date of birth and outputs it in the form of
* this example:
*
* > You were born on the 21st of November, 2012
*
* The program should be implemented so that separate functions, month(), year(), and day(),
* manage the input of the corresponding numerical values. Don’t forget leap
* years—February 29, 2017, is not allowed!
*/
import <iostream>;
import <format>;
import <chrono>;
import <string>;
unsigned validate_input(unsigned lower_limit, unsigned upper_limit,
const std::string& description);
unsigned year(unsigned lower_limit, unsigned upper_limit);
unsigned month(unsigned lower_limit, unsigned upper_limit);
unsigned day(unsigned lower_limit, unsigned upper_limit);
unsigned get_upper_day_limit(unsigned birth_month, int birth_year);
std::string get_output_day_str(unsigned day);
int main()
{
const auto now{ std::chrono::system_clock::now() };
const std::chrono::year_month_day ymd{ std::chrono::floor<std::chrono::days>(now) };
const int current_year{ static_cast<int>(ymd.year()) };
const unsigned lower_year_limit = current_year - 160; // lower birth year
// limit is 160 years ago
const unsigned lower_month_limit{ 1 };
const unsigned upper_month_limit{ 12 };
const unsigned birth_year{ year(lower_year_limit, current_year) };
const unsigned birth_month{ month(lower_month_limit, upper_month_limit) };
const unsigned lower_day_limit{ 1 };
const unsigned upper_day_limit{ get_upper_day_limit(birth_month, birth_year) };
const unsigned birth_day{ day(lower_day_limit, upper_day_limit) };
const std::string output_day_str{ get_output_day_str(birth_day) };
std::cout << std::format("You were born on the {} of {:B}, {}\n",
output_day_str, std::chrono::month{ birth_month }, birth_year);
}
std::string get_output_day_str(const unsigned day)
{
std::string output_day_str;
std::string day_str{ std::to_string(day) };
if (day_str.ends_with("1"))
{
output_day_str = day_str += "st";
}
else if (day_str.ends_with("2"))
{
output_day_str = day_str += "nd";
}
else if (day_str.ends_with("3"))
{
output_day_str = day_str += "rd";
}
else
{
output_day_str = day_str += "th";
}
return output_day_str;
}
unsigned get_upper_day_limit(const unsigned birth_month, const int birth_year)
{
unsigned upper_day_limit{};
switch (birth_month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
upper_day_limit = 31;
case 4: case 6: case 9: case 11:
upper_day_limit = 30;
case 2:
std::chrono::year year{ birth_year };
if (year.is_leap())
{
upper_day_limit = 29;
}
else
{
upper_day_limit = 28;
}
}
return upper_day_limit;
}
unsigned validate_input(const unsigned lower_limit, const unsigned upper_limit,
const std::string& description)
{
unsigned value{};
std::cout << "Please enter your " << description << " now: ";
std::cin >> value;
if (value < lower_limit || value > upper_limit)
{
while (value < lower_limit || value > upper_limit)
{
std::cout << "invalid " << description << "! Try again: ";
std::cin >> value;
}
std::cin.ignore(32767, '\n');
}
return value;
}
unsigned day(const unsigned lower_limit, const unsigned upper_limit)
{
return validate_input(lower_limit, upper_limit, "day of birth");
}
unsigned month(const unsigned lower_limit, const unsigned upper_limit)
{
return validate_input(lower_limit, upper_limit, "month of birth");
}
unsigned year(const unsigned lower_limit, const unsigned upper_limit)
{
return validate_input(lower_limit, upper_limit, "year of birth");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment