I have an assignment that essentially requires me to use a class to output the day of the week based upon input from the user EX: user enters sat (first three letters) --> output = This day of the week is: 6. We're also required for the program to also ouput the next six days following the day specified by the user, ex:
Input:
tue
Output:
This day of the week is: 2
This day of the week is: 3
This day of the week is: 4
This day of the week is: 5
This day of the week is: 6
This day of the week is: 7
This day of the week is: 1
My program is bit messy as I initially misunderstood the question. I was able to develop a functioning program that allows the user to input a number for the day, but not the first three letters as that part of the code seems not to be functioning whatsoever.
Any suggestions or solutions would be immensely appreciated. Thank you in advance.
#include <iostream>
#include <string>
using namespace std;
//
// Definition of the DayOfWeek class
//
class DayOfWeek
{
public:
DayOfWeek(int dayNum);
// Precondition: The parameter dayNum contains a valid
// day number (1 - 7)
// Postcondition: The member variable day has been set to
// the value of the parameter dayNum.
DayOfWeek();
// Sets the member variable month to 1 (defaults to January).
DayOfWeek(char fL, char sL, char tL);
void outputDayNumber();
// Postcondition: The member variable day has been output
// to the screen if it is valid; otherwise a "not valid"
// message is printed.
void outputDayLetters();
// Postcondition: The first three letters of the name of the
// day has been output to the screen if the day is
// valid (1 - 12); otherwise a message indicating the month
// is not valid is output.
DayOfWeek NextDay();
// Precondition: The month is defined and valid.
// Returns the next day as an object of type Day.
private:
int day;
};
int main()
{
//
// Variable declarations
//
int DayNum;
string DayWord;
char letter1, letter2, letter3; // first 3 letters of the day
char testAgain; // y or n - loop control
//
// Loop to test the next month function
//
do {
cout << endl;
cout << "Enter a day number: ";
cin >> DayNum;
DayOfWeek testDay(DayNum);
cout << endl;
cout << "This day ..." << endl;
testDay.outputDayNumber();
testDay.outputDayLetters();
DayOfWeek next = testDay.NextDay();
cout << endl;
cout << "Next day ..." << endl;
next.outputDayNumber();
next.outputDayLetters();
//
// See if user wants to try another month
//
cout << endl;
cout << "Do you want to test again? (y or n) ";
cin >> testAgain;
} while (testAgain == 'y' || testAgain == 'Y');
return 0;
}
DayOfWeek::DayOfWeek()
{
day = 1;
}
DayOfWeek::DayOfWeek(int dayNum)
{
if (dayNum >= 1 && dayNum <= 7)
day = dayNum;
else {
dayNum = 1;
}
}
void DayOfWeek::outputDayNumber()
{
if (day >= 1 && day <= 7)
cout << "Day: " << day << endl;
else
cout << "Error - The day is not valid!" << endl;
}
void DayOfWeek::outputDayLetters()
{
switch (day)
{
case 1:
cout << "1" << endl;
break;
case 2:
cout << "2" << endl;
break;
case 3:
cout << "3" << endl;
break;
case 4:
cout << "4" << endl;
break;
case 5:
cout << "5" << endl;
break;
case 6:
cout << "6" << endl;
break;
case 7:
cout << "7" << endl;
break;
default:
cout << "Error - the day is not valid!" << endl;
}
}
DayOfWeek::DayOfWeek(char firstL, char secondL, char thirdL)
{
/**
*check to for the first characters or letter of the day
*prints the day based on the characters user input
*check if the characters is valid
*/
if (firstL >= 65 && firstL <= 90) {
firstL += 32;
}
if (secondL >= 65 && secondL <= 90) {
secondL += 32;
}
if (thirdL >= 65 && thirdL <= 90) {
thirdL += 32;
}
if (firstL == 'm' && secondL == 'o' && thirdL == 'n') {
day = 1;
}
else if (firstL == 't' && secondL == 'u' && thirdL == 'e') {
day = 2;
}
else if (firstL == 'w' && secondL == 'e' && thirdL == 'd') {
day = 3;
}
else if (firstL == 't' && secondL == 'h' && thirdL == 'u') {
day = 4;
}
else if (firstL == 'f' && secondL == 'r' && thirdL == 'i') {
day = 5;
}
else if (firstL == 's' && secondL == 'a' && thirdL == 't') {
day = 6;
}
else if (firstL == 's' && secondL == 'u' && thirdL == 'n') {
day = 7;
}
else {
day = 0;
cout << "Invalid Day" << endl;
}
}
DayOfWeek DayOfWeek::NextDay() {
int d = (day % 7) + 1;
return DayOfWeek(d);
}
UPDATE:
Changed my code up entirely but still need to implement the next day and then
the next 6 days function.
NEW CODE :
#include <iostream>
#include <string>
using namespace std;
class DayOfWeek
{
string day;
public:
DayOfWeek();
DayOfWeek(string day_name);
void print_car(ostream& ins);
};
int main() {
string day_name;
cout << "Enter the first three letters of the day :" << endl;
cin >> day_name;
DayOfWeek my_car(day_name);
my_car.print_car(cout);
return 0;
}
DayOfWeek::DayOfWeek(string day_name) {
day = day_name;
}
void DayOfWeek::print_car(ostream& outs) {
if (day == "Mon" || day == "mon") {
outs << "This is day 1 of the week" << endl;
}
if (day == "Tue" || day == "tue") {
outs << "This is day 2 of the week" << endl;
}
if (day == "Wed" || day == "wed") {
outs << "This is day 3 of the week" << endl;
}
if (day == "Thu" || day == "thu") {
outs << "This is day 4 of the week" << endl;
}
if (day == "Fri" || day == "fri") {
outs << "This is day 5 of the week" << endl;
}
if (day == "Sat" || day == "sat") {
outs << "This is day 6 of the week" << endl;
}
if (day == "Sun" || day == "sun") {
outs << "This is day 7 of the week" << endl;
}
}
Final Update:
I am nearly at a final solution but I am having a issues declaring a
new object for the final part of my problem.
The code is here...
#include <iostream>
#include <string>
using namespace std;
class DayOfWeek
{
string day;
// int nday;
public:
DayOfWeek();
DayOfWeek(string day_name);
void print_day(ostream& ins);
};
int main() {
string day_name;
int nday;
cout << "Enter the first three letters of the day :" << endl;
cin >> day_name;
DayOfWeek week_day(day_name);
week_day.print_day(cout);
DayOfWeek next_day;
int d = _____;
int current = (d % 7) + 1;
int count = 0;
while (count < 7) {
next_day = DayOfWeek(current);
next_day.print_day(cout);
count++;
}
return 0;
}
DayOfWeek::DayOfWeek(string day_name) {
day = day_name;
}
void DayOfWeek::print_day(ostream& outs) {
int dayNumber = 0;
if (day == "Mon" || day == "mon") {
dayNumber = 1;
}
if (day == "Tue" || day == "tue") {
dayNumber = 2;
}
if (day == "Wed" || day == "wed") {
dayNumber = 3;
}
if (day == "Thu" || day == "thu") {
dayNumber = 4;
}
if (day == "Fri" || day == "fri") {
dayNumber = 5;
}
if (day == "Sat" || day == "sat") {
dayNumber = 6;
}
if (day == "Sun" || day == "sun") {
dayNumber = 7;
}
outs << "This is day " << dayNumber << " of the week." << endl;
}
I have some issue being able to convert the user inputted name of the day, into an integer that I can use to plug into the next_day function.
I am also having an error in the while loop
while (count < 7) {
next_day = DayOfWeek(current);
next_day.print_day(cout);
count++;
}
specifically line:
next_day = DayOfWeek(current);
The error says that there's no instance of DayOfWeek::DayOfWeek matching the argument list.
I feel like I'm nearly there if not for these couple of bumps.
Code below should do some of what you need.
Instead of using chars, I've used a string. That way you can compare the whole string in one go rather than 1 char at a time.
Also for comparing the input against the day-words, i have created an array of Strings. The index corresponds to the day, i.e 0=sunday, 1=monday etc.
This is neat for 2 reasons, we can compare with a loop easily, and as soon as we find the matching day, we just grab the index and there we have our day number. Store that number, and then we can return that for the day number, or use the day as an index in the array to return the day word instead.
Hopefully this is clear, you still need to make a function to return the next day, but the 3 letter input should work.
#include <iostream>
#include <cctype> // std::tolower
#include <algorithm> // std::transform
class DayOfWeek
{
private:
const static std::string days[7];
private:
int day;
public:
DayOfWeek();
DayOfWeek(int);
DayOfWeek(std::string);
void outputDayNumber();
void outputDayLetters();
};
// if we have an array of strings, we can use these for comparison and also Day value
const std::string DayOfWeek::days[7] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
DayOfWeek::DayOfWeek() {
}
DayOfWeek::DayOfWeek(int dayNum)
{
day = dayNum;
}
DayOfWeek::DayOfWeek(std::string dayWord)
{
day = 0; // set Sunday as default
// truncate the string to 3 letters
if (dayWord.length() > 3)
dayWord = dayWord.substr(0, 3);
// to lower case - makes comparison case insensitive
std::transform(dayWord.begin(), dayWord.end(), dayWord.begin(), [](unsigned char c) { return std::tolower(c);});
// compare with our list of strings, if none found, it will stay as default
for (int i = 0; i < 7; ++i)
if (days[i] == dayWord)
{
day = i;
break;
}
}
void DayOfWeek::outputDayLetters() {
std::cout << std::endl << "Day Letters: " << days[day];
}
void DayOfWeek::outputDayNumber() {
std::cout << std::endl << "Day Numbers: " << day;
}
int main()
{
int dayNum;
std::string dayWord;
std::cout << std::endl << "Enter a weekday: ";
std::cin >> dayWord;
std::cout << std::endl << "You entered " << dayWord;
DayOfWeek dayObject = DayOfWeek(dayWord);
dayObject.outputDayNumber();
dayObject.outputDayLetters();
}
Related
I am making a calendar program in C++ that determines the days of a month in any given year by counting the number of days between January 1st, 1753 all the way to the first day of the given month in the given year. It then divides this number of days by 7 to determine the "offset" that is used to figure out what day the first day of the month begins (example: since January 1st, 1753 is on a Monday, an offset of 2 means that the first day of the month will be on a Wednesday). I completed my code and ran it through several tests when I noticed a very strange bug. For the year 2000, the offset is one higher than it should be (February starts on a Wednesday instead of a Tuesday, etc). This problem doesn't exist in any other leap year, or year ending with "00". It is the only test I am failing, and for the life of me I can't seem to figure out what the problem is.
Here is the code:
//**********************************************************************
#include <iostream>
#include <iomanip>
using namespace std;
int getYear();
int getMonth();
int computeNumDays(int month, int year);
int computeOffset(int month, int year);
bool isLeapYear(int year);
void displayHeading(int month, int year);
void displayTable(int offset, int numDays);
/********************
* MAIN
*********************/
int main()
{
int month = getMonth();
int year = getYear();
int offset = computeOffset(month, year);
int numDays = computeNumDays(month, year);
displayHeading(month, year);
displayTable(offset, numDays);
return 0;
}
/********************
*GETMONTH
*Prompts the user for a month number
*********************/
int getMonth()
{
int month;
//Month number must be between 1 and 12
cout << "Enter a month number: ";
cin >> month;
//Displays an error message if the month is under 1 or over 12
while (month < 1 || month > 12)
{
cout << "Month must be between 1 and 12.\n";
cout << "Enter a month number: ";
cin >> month;
}
return month;
}
/********************
*GETYEAR
* prompts the user for a year
*********************/
int getYear()
{
int year;
cout << "Enter year: ";
cin >> year;
//Displays an error message if the year is less than 1753
while (year < 1753)
{
cout << "Year must be 1753 or later.\n";
cout << "Enter year: ";
cin >> year;
}
cout << "\n";
return year;
}
/********************
*COMPUTENUMDAYS
* For computing the number of days in a month, so we know where to count to when filling in
* the calendar
*********************/
int computeNumDays(int month, int year)
{
int numDays;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
return numDays = 31;
else if (month == 4 || month == 6 || month == 9 || month == 11)
return numDays = 30;
else if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return numDays = 29;
else if (month == 2)
return numDays = 28;
}
/*********************
*COMPUTEOFFSET
*********************/
int computeOffset(int month, int year)
{
int totalYearDays = 0;
int totalMonthDays = 0;
//This counts up all the days between the January 1st of 1753 to January 1st of the users input
//year. Leap years are accounted for with the IF statements and the isLeapYear function
for (int yearCount = 1753; yearCount < year; yearCount++)
{
if (isLeapYear(yearCount))
totalYearDays += 366;
else
totalYearDays += 365;
}
//The days of the month of the user input year are added up here. If the user inputs February(2),
//then it counts the days of each month in between and adds them up.
for (int monthCount = 0; monthCount < month; monthCount++)
{
if (monthCount == 1 || monthCount == 3 || monthCount == 5)
totalMonthDays += 31;
else if (monthCount == 7 || monthCount == 8 || monthCount == 10 || monthCount == 12)
totalMonthDays += 31;
else if (monthCount == 4 || monthCount == 6 || monthCount == 9 || monthCount == 11)
totalMonthDays += 30;
//if the user input year is a leap year, then an extra day to February is added
else if (monthCount == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
totalMonthDays += 29;
else if (monthCount == 2)
totalMonthDays += 28;
}
int offset = (totalYearDays + totalMonthDays) % 7;
return offset;
}
/******************************************
* ISLEAPYEAR
******************************************************/
bool isLeapYear(int yearCount)
{
//Equation for determining if a year is a leap year or not
if ((yearCount % 4 == 0 && yearCount % 100 != 0) || (yearCount % 400 == 0))
return true;
else
return false;
}
/*************************************************
*DISPLAYHEADING
* This is where the Month Name and Year are shown
**************************************************/
void displayHeading(int month, int year)
{
if (month == 1)
cout << "January, " << year << endl;
else if (month == 2)
cout << "February, " << year << endl;
else if (month == 3)
cout << "March, " << year << endl;
else if (month == 4)
cout << "April, " << year << endl;
else if (month == 5)
cout << "May, " << year << endl;
else if (month == 6)
cout << "June, " << year << endl;
else if (month == 7)
cout << "July, " << year << endl;
else if (month == 8)
cout << "August, " << year << endl;
else if (month == 9)
cout << "September, " << year << endl;
else if (month == 10)
cout << "October, " << year << endl;
else if (month == 11)
cout << "November, " << year << endl;
else if (month == 12)
cout << "December, " << year << endl;
return;
}
/********************
*DISPLAYTABLE
*********************/
void displayTable(int offset, int numDays)
{
//days of the week are displayed here
cout << setw(4) << "Su" << setw(4) << "Mo" << setw(4) << "Tu"
<< setw(4) << "We" << setw(4) << "Th" << setw(4) << "Fr" << setw(4)
<< "Sa" << setw(2) << endl;
//WeekBreak counter will be used to add new lines for each week
int weekBreak = 1;
//This IF statement determines the number of days before the first of the month occurs,
// as well as sets the weekBreak counter
if (offset != 6 && offset >= 0)
do
{
cout << setw(4) << " ";
offset--;
weekBreak++;
} while (offset != -1);
//The counter loop here begins putting in the dates, all the way from the first to
//the max number of days in the month
for (int date = 1; date <= numDays; date++)
{
cout << " " << setw(2) << date;
weekBreak++; //weekBreak prevents us from putting more than
//7 dates in a single week
if (weekBreak == 8)
{
cout << "\n"; //once a week hits 7 dates(or 8 spaces), it moves on to a new week
weekBreak = 1;
}
}
//this puts an end to the calander, regardless if weekBreak limit is reached
if (weekBreak >= 2 && weekBreak <= 7)
cout << "\n";
}
It bothers me that it only seems to happen for the year 2000. I'm not sure what the cause could be, so I could really use some feedback.
To debug your code I wrote the following main function:
int main()
{
for (int year = 1753; year <= 2021; year++)
{
for (int month = 1; month <= 12; month++)
{
int offset = computeOffset(month, year);
int numDays = computeNumDays(month, year);
std::chrono::year_month_day date(std::chrono::year(year), std::chrono::month(month), std::chrono::day(1));
std::chrono::weekday day{ std::chrono::sys_days(date) };
int expectedOffset = ((day - std::chrono::Monday).count() + 7) % 7;
if (expectedOffset != offset)
{
std::cout << year << "/" << month << " expected " << expectedOffset << " actual " << offset << "\n";
}
}
}
return 0;
}
This confirms it is indeed only the year 2000 which is incorrect. This suggests its the handling of the leap year every 400 years which is incorrect.
As you have a function for calculating leap years the first thing to try is to use that rather than implementing the same code three times (implementing something 3 times triples the chances of creating a bug). Changing computeNumDays to:
else if (month == 2 && isLeapYear(year))
return numDays = 29;
and computeOffset to:
else if (monthCount == 2 && isLeapYear(year))
totalMonthDays += 29;
fixes the bug.
The cause of the bug is actually the combination of 2 bugs:
in computeOffset monthCount starts from 0 not 1.
the expression monthCount == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) will always be true when year % 400 == 0 is true. The intended expression was monthCount == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
This causes the value of totalMonthDays to be 29 more than it should be for years divisible by 400, after %7 this causes the result of computeOffset to be 1 higher than it should be.
By removing repetition your code can be greatly simplified:
int computeNumDays(int month, int year)
{
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
return isLeapYear(year) ? 29 : 28;
default:
throw std::invalid_argument("invalid month");
}
}
int computeOffset(int month, int year)
{
int totalYearDays = 0;
int totalMonthDays = 0;
//This counts up all the days between the January 1st of 1753 to January 1st of the users input
//year. Leap years are accounted for with the IF statements and the isLeapYear function
for (int yearCount = 1753; yearCount < year; yearCount++)
{
if (isLeapYear(yearCount))
totalYearDays += 366;
else
totalYearDays += 365;
}
//The days of the month of the user input year are added up here. If the user inputs February(2),
//then it counts the days of each month in between and adds them up.
for (int monthCount = 1; monthCount < month; monthCount++)
{
totalMonthDays += computeNumDays(monthCount, year);
}
int offset = (totalYearDays + totalMonthDays) % 7;
return offset;
}
bool isLeapYear(int yearCount)
{
//Equation for determining if a year is a leap year or not
if ((yearCount % 4 == 0 && yearCount % 100 != 0) || (yearCount % 400 == 0))
return true;
else
return false;
}
So basically I just started to learn c++ and have an assignment which I'm totally stuck on, I googled it for days but just can't find out how to make it work.
The assignment is very simply:
Calculate the age of a person based on the user's input (Birth year, month, day).
The user needs to enter enter the day on which they were born (so for example: thursday)
The Program needs to validate if this is indeed correct
Now I am stuck on point 3;
I made a formula that calculates on which day someone is born. And basically that formula outputs a number 0 - 6 and that references to a day (0 would be sunday, 1 would be monday, etc.)
The problem is that a user would input for example thursday, but the program only recognizes nr 4 as thursday. So the program can't confirm or deny that the user is indeed born on a thursday.
To fix that, I tried the following:
This is the formula that calculates the number 0 to 6 (0 should equal sunday for example)
int fdb = ((jcr + mc + ec + birthday - sjc) % 7); //
This is the full code:
int birthdayfdb;
int sunday;
int monday;
int tuesday;
int wednesday;
int thursday;
int friday;
int saturday;
cout <<"On which day are you born?" << endl;
cin >> birthdayfdb; // Here the users inputs the day where he or she is born on
if ((birthdayfdb == sunday && fdb == 0) || (birthdayfdb == monday && fdb == 1) || (birthdayfdb == tuesday && fdb == 2) || (birthdayfdb == wednesday && fdb == 3) || (birthdayfdb == thursday && fdb == 4) || (birthdayfdb == friday && fdb == 5) || (birthdayfdb == saturday && fdb == 6))
{
cout << "This is Correct" << endl;
}
else
{
cout << "This is incorrect" << endl;
return 0;
}
So this does not work because whatever birthday the user enters, it always says that is is correct.
I looked up all sorts of things on the internet (stackflow, youtube, etc) but I can't find out how to do this.
Complete:
#include <iostream>
using namespace std;
int main ( ) {
int birthyear;
int birthmonth;
int birthday;
cout << “What is your birth year?” << endl;
cin >> birthyear;
if ((birthyear > 2008) || (birthyear < 1928))
{
cout <<“You are too old/young.“<< endl;
return 0;
}
cout << "In which month are you born? (Answer should be in
numbers)“<< endl;
cin >> birthmonth;
if (((birthmonth > 9) && (birthmonth == 2008)) || ((birthmonth < 9)
&& (birthmonth == 1928)))
{
cout <<"You are too old/young.”<< endl;
return 0;
}
cout << “On which day are you born?” << endl;
cin >> birthday;
if (((birthday > 24) && (birthmonth == 9) && (birthyear == 2008)) ||
((birthday < 24) && (birthmonth == 9) && (birthyear == 1928)))
{
cout <<"You are too old/young.”<< endl;
return 0;
}
double ageinyears = (2018 - birthyear);
int agemonths = (9 - birthmonth);
int agedays = (24 - birthday);
int totalmonths = ((ageinyears*12) + agemonths);
cout << “Your age is "<<ageinyears<<" jaar, "<<agemonths<<" months,
and " <<agedays<<" days, or "<<totalmonths<<" months.” << endl;
if ((birthday == 24) && (agemonths != 0))
{
cout <<" "<< endl;
cout << “Congratulations on your month anniversary!“<< endl;
cout <<" "<< endl;
}
else
{
cout << " "<< endl;
}
if ((birthday == 24) && (agemonths == 0))
cout <<" "<< endl;
cout << “Congrationlations with your birthday!”<< endl;
cout <<" "<< endl;
}
int jc = birthyear % 100;
int jcr = ((jc + (jc / 4)) % 7);
int ec;
if ((birthyear >= 1900) && (birthyear <= 1999))
{
ec = 0;
}
if ((birthyear >= 2000) && (birthyear <= 2099))
{
ec = 6;
}
int mc;
if ((birthmonth == 1) || (birthmonth == 10))
{
mc = 0;
}
if (birthmonth == 5)
{
mc = 1;
}
if (birthmonth == 8)
{
mc = 2;
}
if ((birthmonth == 2) || (birthmonth == 3) || (birthmonth == 11))
{
mc = 3;
}
if (birthmonth == 6)
{
mc = 4;
}
if ((birthmonth == 9) || (birthmonth == 12))
{
mc = 5;
}
if ((birthmonth == 4) || (birthmonth == 7))
{
mc = 6;
}
int sjc;
if ((birthmonth == 1 || 2) && (birthyear % 4 == 0 ))
{
sjc = 1;
}
else
{
sjc = 0;
}
int fdb = ((jcr + mc + ec + birthday - sjc) % 7);
cout << fdb << endl;
std::string birthdayfdb;
cout <<"On which day are you born?” << endl;
cin >> birthdayfdb;
bool check = false;
switch(fdb){
case 0:
if(birthdayfdb() == “sunday”) check = true;
case 1:
if(birthdayfdb() == “monday”) check = true;
case 2:
if(birthdayfdb() == “tuesday”) check = true;
case 3:
if(birthdayfdb() == “wednesday”) check = true;
case 4:
if(birthdayfdb() == “thursday”) check = true;
case 5:
if(birthdayfdb() == “friday”) check = true;
case 6:
if(birthdayfdb() == “saturday”) check = true;
}
if(check){
cout << "This is correct" << endl;
}
else{
cout << "This is incorrect" << endl;
}
}
You need to use a Switch Statement in order to achieve what you are looking for.
This is your full code fixed:
#include <iostream>
#include <string>
using namespace std;
int main ( ){
int birthyear;
int birthmonth;
int birthday;
cout << "What is your birth year?" << endl;
try{
cin >> birthyear;
}
catch(...){
cout << "A number is the only accepted input" << endl;
return 0;
}
cout << "In which month are you born? (Answer should be in numbers from 1 to 12)"<< endl;
try{
cin >> birthmonth;
}
catch(...){
cout << "A number is the only accepted input" << endl;
return 0;
}
cout << "On which day are you born?" << endl;
try{
cin >> birthday;
}
catch(...){
cout << "A number is the only accepted input" << endl;
return 0;
}
if ((birthday > 24 || birthday < 1) && (birthmonth > 9 || birthmonth < 1) && (birthyear > 2008 || birthyear < 1918)) {
cout <<"You are too old/young."<< endl;
return 0;
}
double ageinyears = (2018 - birthyear);
int agemonths = (9 - birthmonth);
int agedays;
switch (birthmonth){
case 2:
if((birthyear%100 == 0) && (birthyear%400 == 0)){
agedays = (29 - birthday);
}
else if(birthyear%4 == 0 && birthyear%100 != 0){
agedays = (29 - birthday);
}
else{
agedays = (28 - birthday);
}
break;
case 4:
agedays = (30 - birthday);
break;
case 11:
agedays = (30 - birthday);
break;
case 6:
agedays = (30 - birthday);
break;
case 9:
agedays = (30 - birthday);
break;
default:
agedays = (31 - birthday);
break;
}
int totalmonths = ((ageinyears*12) + agemonths);
cout << "Your age is " <<ageinyears<< " year, "<<agemonths<<" months, and " <<agedays<<" days, or "<<totalmonths<<" total months." << endl;
if ((birthday == 24) && (agemonths == 0)){
cout <<" "<< endl;
cout << "Congrationlations with your birthday!"<< endl;
cout <<" "<< endl;
}
else if ((agedays == 24) && (agemonths != 0)) {
cout <<" "<< endl;
cout << "Congratulations on your month anniversary!"<< endl;
cout <<" "<< endl;
}
int jc = birthyear % 100;
int jcr = ((jc + (jc / 4)) % 7);
int ec;
if ((birthyear >= 1900) && (birthyear <= 1999)){
ec = 0;
}
else if ((birthyear >= 2000) && (birthyear <= 2099)){
ec = 6;
}
int mc;
switch(birthmonth){
case 1:
mc = 0;
break;
case 2:
mc = 3;
break;
case 3:
mc = 3;
break;
case 4:
mc = 6;
break;
case 5:
mc = 1;
break;
case 6:
mc = 4;
break;
case 7:
mc=6;
break;
case 8:
mc = 2;
break;
case 9:
mc = 5;
case 10:
mc = 0;
break;
case 11:
mc = 3;
break;
case 12:
mc = 5;
break;
}
int sjc;
if ((birthmonth == 1 || 2) && (birthyear % 4 == 0 )){
sjc = 1;
}
else{
sjc = 0;
}
int fdb = ((jcr + mc + ec + birthday - sjc) % 7);
std::string birthdayfdb;
cout <<"On which day are you born? E.G. monday" << endl;
try{
cin >> birthdayfdb;
}
catch(...){
cout << "only english days name are accepted!";
return 0;
}
cin >> birthdayfdb;
bool check = false;
switch(fdb){
case 0:
if(birthdayfdb == "sunday") check = true;
break;
case 1:
if(birthdayfdb == "monday") check = true;
break;
case 2:
if(birthdayfdb == "tuesday") check = true;
break;
case 3:
if(birthdayfdb == "wednesday") check = true;
break;
case 4:
if(birthdayfdb == "thursday") check = true;
break;
case 5:
if(birthdayfdb == "friday") check = true;
break;
case 6:
if(birthdayfdb == "saturday") check = true;
break;
}
if(check){
cout << "This is correct" << endl;
}
else{
cout << "This is incorrect" << endl;
}
}
As you can see, we used a boolean variable (bool check;) to save if the user input is validated in order to print (later) the messagge on the screen.
Of course you could just print inside the Switch Case Statement like this:
case 0:
if(birthdayfdb == "sunday"){
cout << "This is correct" << endl;
}
else{
cout << "This is incorrect"<< endl;
}
But this would make it longer and a bit slower. Also, in the above case there are alot of repetition (pretty much the same if statement on every case) while is preferred to just code one single print while saving on a bool variable if the validation of the input is OK.
FIXES:
A little mistake that causes ALOT of problem: you were using ” insted of " to denote strings
You were using alot of If statement instead of using else if
For the birthday calculation is better to use a switch statement
I removed some useless blank output e.g. cout << " " <<endl;
You were declaring some string variable as int e.g. int birthdayfdb
You were checking the user input 3 times while most of the check was a repetition. I change it with only one input validation at the end of the inputs
Another one little mistake that causes alot of problems. You were refering to birthdayfdb as a function and not a string. E.G. if(birthdayfdb() == "sunday") check = true;
A very BIG MISTAKE is the absence of errors handling and a well-done input validation! e.g. If the user type "foo" instead of his birthyear
for further information about String, Data Types, Switch Case statement and Try/Catch statement read the linked documentation!
I am writing a "time travel" program which is supposed to ask the user for the current time, their target travel time, relay those values to be converted into minutes in a function and then based on if the time difference is too high it will not allow the time travel or if it is allowed it will print if they are in the future or the past. My issue right now is that the current time, which is only supposed to be relevant the first iteration, or the first "jump" of the program is not being updated after the jump occurs, and the program defaults to it instead of the target time, which is supposed to be the technical "current time" after the jump has occurred. I have been trying to figure this out for hours and I can't, so I am hoping someone could help me out.
Thank you for your time
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int compute_time_difference(int c_hrs, int c_mins, bool c_am, int t_hrs, int t_mins, bool t_am);
void print_future();
void print_past();
void print_SecurityProtocol();
int main()
{
int c_hrs, c_mins;
int t_hrs, t_mins;
int system_time2;
int time_difference2;
bool c_am = 0;
bool t_am = 0;
char c, c2, Y, N, y, n, jumpAgain;
string am_or_pm_current, am_or_pm_target;
bool g_stop = true;
cout << "Welcome to Po Sled" << endl;
cout << "\tSystem booting..." << endl;
for (int i = 0; i<1; i++) //for loop to run once
{
cout << "\n\tEnter current time below: " << endl;
cout << "\t>Enter hour: "; //User inputs current time in hours
cin >> c_hrs;
while (c_hrs > 12 || c_hrs < 1)
{
cout << "Error: Please enter an hour in the range [1, 12]: ";
cin >> c_hrs;
}
cout << "\t>Enter minutes: "; //User inputs current time in minutes
cin >> c_mins;
while (c_mins > 59 || c_mins < 0) {
cout << "Error: Please enter minutes in the range [0, 59]: ";
cin >> c_mins;
}
cout << "\t>Is it AM or PM?: "; //Classifying if current time is AM or PM
cin >> am_or_pm_current;
while (am_or_pm_current != "am" && am_or_pm_current != "AM" && am_or_pm_current != "pm" && am_or_pm_current != "PM") { //Checks if valid input, if not repeats message until valid
cout << "\tError: Please enter AM/am or PM/pm: ";
cin >> am_or_pm_current;
}
if ((am_or_pm_current == "am") || (am_or_pm_current == "AM"))
{
c_am = 1;
}
else if ((am_or_pm_current == "pm") || (am_or_pm_current == "PM"))
{
c_am = 0;
}
cout << "\n\tCurrent system time set to " << c_hrs << ":" << setw(2) << setfill('0') << c_mins << am_or_pm_current << endl;
cout << "\n\t\tIs this time correct (Y or N)? ";
cin >> c;
while (c != 'Y' && c != 'y' && c != 'n' && c != 'N')
{
cout << "\t\t\tError: Please enter Y/y or N/n: ";
cin >> c;
}
if (c == 'N' || c == 'n')
{
continue;
}
else
{
cout << "\n\tSystem initializing and TARDIS unit warming...." << endl;
cout << "\tThe Po Sled is engaged and ready for input." << endl;
}
}
do {
//Starts a loop for target jump
cout << "\n\tEnter target time below: " << endl; //Enters target time of jump
cout << "\t>Enter Hour: ";
cin >> t_hrs;
while (t_hrs > 12 || t_hrs < 1) {
cout << "Error: Please enter an hour in the range [1, 12]: ";
cin >> t_hrs;
}
cout << "\t>Enter minutes: ";
cin >> t_mins;
while (t_mins > 59 || t_mins < 0) {
cout << "\tError: Please enter minutes in the range [0, 59]: ";
cin >> t_mins;
}
cout << "\n\tIs it AM or PM?: ";
cin >> am_or_pm_target; //Classifying if target time is AM or PM
while (am_or_pm_current != "am" && am_or_pm_current != "AM" && am_or_pm_current != "pm" && am_or_pm_current != "PM")
{ //Validates input is AM or PM
cout << "\tError: Please enter AM/am or PM/pm: ";
cin >> am_or_pm_target;
}
if ((am_or_pm_target == "am") || (am_or_pm_target == "AM"))
{
t_am = 1;
}
else if ((am_or_pm_target == "pm") || (am_or_pm_target == "PM"))
{
t_am = 0;
}
cout << "\tTarget time set to " << t_hrs << ":" << setw(2) << setfill('0') << t_mins << am_or_pm_target; //Sets target time
cout << "\n\t\tIs this time correct (Y or N)? "; //Validates if target time entered is correct
cin >> c2;
while (c2 != 'Y' && c2 != 'y' && c2 != 'n' && c2 != 'N')
{
cout << "\t\t\tError: Please enter Y/y or N/n: ";
cin >> c2;
}
time_difference2 = compute_time_difference(c_hrs, c_mins, c_am, t_hrs, t_mins, t_am);
if (time_difference2 > 360) //If time difference is greater than 6 hours prints error function
{
print_SecurityProtocol();
continue;
}
if (c2 == 'N' || c2 == 'n')
{
continue;
}
cout << "\tJump was made, the current time is " << t_hrs << ":" << setw(2) << setfill('0') << t_mins << am_or_pm_target << endl;
if (time_difference2 < 0 && time_difference2 > -360) //If time difference is less than 0 prints past function
{
print_past();
}
else if (time_difference2 >= 0 && time_difference2 <= 360) //If time difference is ahead of current time prints future function
{
print_future();
}
cout << "\tWould you like to jump again (Y/N)? ";
cin >> jumpAgain;
while (jumpAgain != 'Y' && jumpAgain != 'y' && jumpAgain != 'n' && jumpAgain != 'N') //Input validation
{
cout << "\t\t\tError: Please enter Y/y or N/n: ";
cin >> jumpAgain;
}
if (jumpAgain == 'n' || jumpAgain == 'N') //User exiting program
{
if (time_difference2 < 0)
{
cout << "\t\tSystem shutting down; enjoy the past.\n" << endl;
}
else if (time_difference2 >= 0 && time_difference2 < 360)
{
cout << "\t\tSystem shutting down; enjoy the future.\n" << endl;
}
}
if (jumpAgain == 'Y' || jumpAgain == 'y')
{
continue;
}
} while (jumpAgain != 'n' && jumpAgain != 'N');
return 0;
}
int compute_time_difference(int c_hrs, int c_mins, bool c_am, int t_hrs, int t_mins, bool t_am) //Computes time differences.
{
int currentTime_hours, currentTime_minutes, targetTime_hours, targetTime_minutes, currentTime, targetTime;
int time_difference;
if (c_am == 1) //if c_am is true and it is morning
{
if (c_hrs == 12)
{
currentTime_hours = c_hrs * 0;
}
else if (c_hrs != 12)
{
currentTime_hours = (c_hrs * 60);
currentTime_minutes = c_mins;
currentTime = currentTime_hours + currentTime_minutes; //Sets the value of the current time
}
}
else if (c_am == 0) //if c_am is false and it is afternoon time
{
if (currentTime_hours == 12)
{
c_hrs = c_hrs * 60;
}
else if (currentTime_hours != 12)
{
currentTime_hours = ((c_hrs + 12) * 60);
currentTime_minutes = c_mins;
currentTime = currentTime_hours + currentTime_minutes; //Sets the value of the current time
}
}
if (t_am == 1) //if t_am is true and it is morning time
{
if (targetTime_hours == 12) //if target hours equal to 12 special math
{
targetTime_hours = t_hrs*0;
}
else if (targetTime_hours != 12) //else do this math
{
targetTime_hours = ((t_hrs) * 60);
targetTime_minutes = t_mins;
targetTime = targetTime_hours + targetTime_minutes;
}
}
else if (t_am == 0) //if target time equal to pm then do this math
{
if (targetTime_hours == 12)
{
targetTime_hours = t_hrs * 60;
}
else if (targetTime_hours != 12) //else if target time not equal to 12 then do normal pm math
{
targetTime_hours = ((t_hrs + 12) * 60);
targetTime_minutes = t_mins;
targetTime = targetTime_hours + targetTime_minutes;
}
}
time_difference = targetTime - currentTime;
cout << "the difference computed is " << time_difference;
return time_difference;
}
void print_SecurityProtocol() //Function which prints security protocol error message
{
cout << "\tSecurity Protocols Engaging" << endl;
cout << "\t\tError: The time difference is greater than 6 hours." << endl;
cout << "\t\t\tPlease re-enter target time." << endl;
}
void print_past() //Function that prints when a user is in the past
{
cout << "\tHold onto your lower posterior regions" << endl;
cout << "\n\t\tYou are now in the relative past" << endl;
}
void print_future() //Function that prints when a user is in the future
{
cout << "\tHold onto your lower posterior regions" << endl;
cout << "\n\t\tYou are now in the relative future " << endl;
}
Why do you not use a system time call, instead of getting user input for the 'current time'? Also, use a 24-hour clock instead of a 12-hour and you have removed the need to cater for am/pm within your process.
AM n ot much of a coder but c_hrs*60 would be (at least) 60 hours and (at most) 24*60 which, with the exception of a drive across Europe, Russia, Australia or the Northern US would be excessive time recording. Do you not mean to refer to MINUTES instead of hours (c_mins*60)?
Here's the question:
Define a class called Month that is an abstract data type for a month. Your class will have one member variable of type int to represent a month (1 for January, 2 for February, and so forth). Include all the following member functions: a constructor to set the month using the first three letters in the name of the month as three arguments, a constructor to set the month using an integer as an argument (1 for January, 2 for February, and so forth), a default constructor, an input function that reads the month as an integer, an input function that reads the month as the first three letters in the name of the month, an output function that outputs the month as an integer, an output function that outputs the month as the first three letters in the name of the month, and a member function that returns the next month as a value of type Month . Embed your class definition in a test program.
#include <iostream>
using namespace std;
class Month
{
public:
Month (char letter1, char letter2, char letter3);
Month (int numOfMonth);
Month ();
void inputAsNum(); // read month as integer
void inputAsCh(); // read first three chars of month
void outputAsCh() const;
void outputAsNum() const;
Month nextMonth();
private:
int month;
};
int main()
{
Month test(5);
//test.inputAsNum();
cout << "Current month is " << endl;
test.outputAsCh();
test.outputAsNum();
cout << endl;
test.nextMonth();
cout << "Next month is " <<endl;
test.outputAsCh();
test.outputAsNum();
cout << endl;
Month test2('a','p','r');
//test2.inputAsCh();
cout << "Current month is " << endl;
test2.outputAsCh();
test2.outputAsNum();
cout << endl;
test2.nextMonth();
cout << "Next month is " <<endl;
test2.outputAsCh();
test2.outputAsNum();
cout << endl;
Month test3;
test3.inputAsNum();
cout << "Current month is " << endl;
test3.outputAsCh();
test3.outputAsNum();
cout << endl;
test3.nextMonth();
cout << "Next month is " <<endl;
test3.outputAsCh();
test3.outputAsNum();
cout << endl;
Month test4;
test4.inputAsCh();
cout << "Current month is " << endl;
test4.outputAsCh();
test4.outputAsNum();
cout << endl;
test4.nextMonth();
cout << "Next month is " <<endl;
test4.outputAsCh();
test4.outputAsNum();
cout << endl;
return 0;
}
Month::Month (char letter1, char letter2, char letter3)
{
if ((letter1 == 'j')&&(letter2 == 'a')&&(letter3 == 'n'))
month= 1;
else if ((letter1 == 'f')&&(letter2 == 'e')&&(letter3 == 'b'))
month= 2;
else if ((letter1 == 'm')&&(letter2 == 'a')&&(letter3 == 'r'))
month= 3;
else if ((letter1 = 'a')&&(letter2 == 'p')&&(letter3 == 'r'))
month= 4;
else if ((letter1 == 'm')&&(letter2 == 'a')&&(letter3 == 'y'))
month= 5;
else if ((letter1 == 'j')&&(letter2 == 'u')&&(letter3 == 'n'))
month= 6;
else if ((letter1 == 'j')&&(letter2 == 'u')&&(letter3 == 'l'))
month= 7;
else if ((letter1 == 'a')&&(letter2 == 'u')&&(letter3 == 'g'))
month= 8;
else if ((letter1 == 's')&&(letter2 == 'e')&&(letter3 == 'p'))
month= 9;
else if ((letter1 == 'o')&&(letter2 == 'c')&&(letter3 == 't'))
month= 10;
else if ((letter1 == 'n')&&(letter2 == 'o')&&(letter3 == 'v'))
month= 11;
else if ((letter1 == 'd')&&(letter2 == 'e')&&(letter3 == 'c'))
month= 12;
}
Month::Month (int numOfMonth)
:month(numOfMonth)
{ }
Month::Month ()
:month(1)
{ }
void Month::inputAsNum()
{
int num;
cout << "Enter num of month => ";
cin >> num;
month = num;
}
void Month::inputAsCh()
{
char c1,c2,c3;
cout << "Enter three letters of month => ";
cin >> c1 >> c2 >> c3;
Month::Month(c1,c2,c3);
}
void Month::outputAsCh() const
{
if (month == 1)
cout << "Jan ";
else if (month == 2)
cout << "Feb ";
else if (month == 3)
cout << "Mar ";
else if (month == 4)
cout << "Apr ";
else if (month == 5)
cout << "May ";
else if (month == 6)
cout << "Jun ";
else if (month == 7)
cout << "Jul ";
else if (month == 8)
cout << "Aug ";
else if (month == 9)
cout << "Sep ";
else if (month == 10)
cout << "Oct ";
else if (month == 11)
cout << "Nov ";
else if (month == 12)
cout << "Dec ";
}
void Month::outputAsNum() const
{
cout << month;
}
Month Month::nextMonth()
{
if (month < 12)
month++;
else if (month == 12)
month = 1;
return Month(month);
}
The code runs just fine. I try that calling constructor Month::Month (char letter1, char letter2, char letter3) from member function void Month::inputAsCh() . I can solve the problem by changing definition of Month::inputAsCh() and copy paste definitions of the constructor into the function. But, just out of curiosity, can be a constructor called from member function ? If it's okey, Month::inputAsCh() works wrong, I also try on Month test4 variable.
Output Expected Output
------------- -----------------
Current month is Current month is
Nov 11 Nov 11
Next month is Next month is
Dec 12 Dec 12
Current month is Current month is
Apr 4 Apr 4
Next month is Next month is
May 5 May 5
Enter num of month => 2 Enter num of month => 2
Current month is Current month is
Feb 2 Feb 2
Next month is Next month is
Mar 3 Mar 3
Enter three letters of month => apr Enter three letters of month => apr
Current month is Current month is
Jan 1 Apr 4
Next month is Next month is
Feb 2 May 5
Month::Month(c1,c2,c3);
That line doesn't update the current object. It should be an error because Month::Month names the constructor in that context, but some compilers (notably clang) will interpret it as the construction of a temporary object instead (thanks to user657267 for the correction).
You could factor out your month calculation code into a separate function, then call that from both your constructor and your inputAsCh function:
void setMonth(char letter1, char letter2, char letter3)
{
if ((letter1 == 'j')&&(letter2 == 'a')&&(letter3 == 'n'))
month= 1;
else if ((letter1 == 'f')&&(letter2 == 'e')&&(letter3 == 'b'))
month= 2;
else if ((letter1 == 'm')&&(letter2 == 'a')&&(letter3 == 'r'))
month= 3;
else if ((letter1 = 'a')&&(letter2 == 'p')&&(letter3 == 'r'))
month= 4;
else if ((letter1 == 'm')&&(letter2 == 'a')&&(letter3 == 'y'))
month= 5;
else if ((letter1 == 'j')&&(letter2 == 'u')&&(letter3 == 'n'))
month= 6;
else if ((letter1 == 'j')&&(letter2 == 'u')&&(letter3 == 'l'))
month= 7;
else if ((letter1 == 'a')&&(letter2 == 'u')&&(letter3 == 'g'))
month= 8;
else if ((letter1 == 's')&&(letter2 == 'e')&&(letter3 == 'p'))
month= 9;
else if ((letter1 == 'o')&&(letter2 == 'c')&&(letter3 == 't'))
month= 10;
else if ((letter1 == 'n')&&(letter2 == 'o')&&(letter3 == 'v'))
month= 11;
else if ((letter1 == 'd')&&(letter2 == 'e')&&(letter3 == 'c'))
month= 12;
}
Month::Month (char letter1, char letter2, char letter3)
{
setMonth(letter1, letter2, letter3);
}
void Month::inputAsCh()
{
char c1,c2,c3;
cout << "Enter three letters of month => ";
cin >> c1 >> c2 >> c3;
setMonth(c1,c2,c3);
}
Incidentally, your setMonth function could be greatly simplified by creating a std::string from those chars and comparing with that instead.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am having to write a program for a class I'm taking. I have to take a birth date in numerical form (mm-dd-yyyy) and put it into a different format (Month day, year). I feel like my code is correct, but whenever my do while loop gets to the hyphen, it crashes. It compiles correctly, and Visual Studio isn't popping up any error until it runs, so I really don't know what's wrong. I've included the entire code. Also, use of the try/catch block is required for this assignment. Can anyone tell me why this loop doesn't like to check for hyphens? Thanks in advance.
#include <iostream>
#include <string>
using namespace std;
int get_digit(char c) {return c - '0';}
int main() {
string entry = "";
short month = 0;
int day = 0;
int year = 0;
bool error = false;
int temp = 0;
try {
cout << "Enter your birthdate in the form M-D-YYYY: ";
cin >> entry;
int x = 0;
do {
month *= 10;
temp = get_digit(entry[x]);
month += temp;
x += 1;
} while (entry[x] != '-');
if (month > 12) {
throw month;
}
x += 1;
do {
day *= 10;
temp = get_digit(entry[x]);
day += temp;
x += 1;
} while (entry[x] != '-');
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
if (day > 31) {
throw day;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day > 30) {
throw day;
}
} else {
if (day > 29) {
throw day;
}
}
x += 1;
do {
year *= 10;
temp = get_digit(entry[x]);
year += temp;
x += 1;
} while (entry[x] != '\n');
if ((year % 4) != 0) {
if (month == 2 && day > 28) {
throw day;
}
}
switch (month) {
case 1:
cout << "January ";
case 2:
cout << "February ";
case 3:
cout << "March ";
case 4:
cout << "April ";
case 5:
cout << "May ";
case 6:
cout << "June ";
case 7:
cout << "July ";
case 8:
cout << "August ";
case 9:
cout << "September ";
case 10:
cout << "October ";
case 11:
cout << "November ";
case 12:
cout << "December ";
}
cout << day << ", " << year << endl;
} catch (short) {
cout << "Invalid Month!" << endl;
} catch (int) {
cout << "Invalid Day!" << endl;
}
system("pause");
return 0;
}
There is no newline character in your entry string, so x keeps getting incremented and causes buffer overrun for entry[x]. You need to look for the end of the string instead:
do {
year *= 10;
temp = get_digit(entry[x]);
year += temp;
x += 1;
} while (entry[x] != '\0');