I don't understand why this code isn't performing properly - c++

/* Program Name: BadDate.cpp
Function: This program determines if a date entered by the user is valid.
Input: Interactive
Output: Valid date is printed or user is alerted that an invalid date was entered
*/
#include <iostream>
bool validateDate(int, int, int);
using namespace std;
int main()
{
// Declare variables
int year;
int month;
int day;
const int MIN_YEAR = 0, MIN_MONTH = 1, MAX_MONTH = 12, MIN_DAY = 1, MAX_DAY = 31;
bool validDate = true;
This is the work of the housekeeping() method
Get the year, then the month, then the day
int housekeeping() {
cout << "Please enter a year: "<< endl;
cin >> year;
cout << "Please enter a month: "<< endl;
cin >> month;
cout << "Please enter a day: "<< endl;
cin >> day;
}
This is the work of the detailLoop() method
Check to be sure date is valid
int detailLoop() {
if(year <= MIN_YEAR) // invalid year
validDate = false;
else if (month < MIN_MONTH || month > MAX_MONTH) // invalid month
validDate = false;
else if (day < MIN_DAY || day > MAX_DAY) // invalid day
validDate = false;
}
This is the work of the endOfJob() method
test to see if date is valid and output date and whether it is valid or not
int endOfJob()
{
if(validDate == true)
{
// Output statement
cout << " Your date is valid!"<< endl;
}
else
{
// Output statement
cout << " Your date is not valid!"<< endl;
}
}
} // end of main() function

Related

How to make one function's if/else condition control other function in a structure?

We got an assignment where we were supposed to make a birthday wisher. Now whenever the input for month date and year is invalid ( such as negative or zero or beyond the range of months and days) the program should not proceed forth. How to make it do that?
#include <iostream>
using namespace std;
struct birthday_wisher {
int date;
int month;
int year;
int todaysdatedd,todaysdatemm;
void getdob() {
cout << "enter your date of birth (dd/mm/yy) " << endl;
cin >> date >> month >> year;
if ((todaysdatedd > 0 && todaysdatedd <= 31) && (todaysdatemm > 0 && todaysdatemm <= 12) && year>0 )
{
cout << "you have entered a valid date " << endl;
}
else
{
cout << "invalid date/ month\n";
}
}
void gettodaysdate() {
cout << "enter today's date (dd/mm)\n";
cin >> todaysdatedd >> todaysdatemm;
if ((todaysdatedd>0 && todaysdatedd<=31) && (todaysdatemm>0 && todaysdatemm<=12))
{
cout << "you have entered a valid date" << endl;
}
else
{
cout << "invalid date/ month";
}
}
void check() {
if (month == todaysdatemm) {
if (date == todaysdatedd)
{
cout << "happy birthday!";
}
}
else
{
cout << "your birthday is not today ;-;\n";
}
}
};
int main()
{
birthday_wisher b1;
b1.getdob();
b1.gettodaysdate();
b1.check();
}
You got a few options.
The brute option: Put exit(int exitCode) after the check fails. This will immediately exit the program e.g.
if (IsNotAValidDate())
{
exit(1);
}
The better option: Make getdob to return bool and make the program peacefully exit if the condition fails.
bool getdob() {
// You might want to check also for 31/30 day months and for February as here are bugs
cout << "enter your date of birth (dd/mm/yy) " << endl;
cin >> date >> month >> year;
return (todaysdatedd > 0 && todaysdatedd <= 31) && (todaysdatemm > 0 && todaysdatemm <= 12) && year>0;
}
int main()
{
birthday_wisher b1;
if (b1.getdob())
{
b1.gettodaysdate();
b1.check();
}
else
{
std::cout << "Invalid date provided\n";
}
return 0;
}

Why does my code not display updated dates? [closed]

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 2 years ago.
Improve this question
Okay so what this program is supposed to do is display the date in M/D/Y format and for some unknown reason it always displays 1/1/1. I have been skimming through this the past 40 mins and still can't understand where I went wrong. Please help me out. Needmorewordstopostthissssssssssssssssssssssssssssssssssssssssssssssss
#include <iostream>
using namespace std;
void displayDate();
class Date{
public:
int month;
int day;
int year;
int mmax;
//functions
int getMonth();
int getDay();
int getYear();
int setMonth();
int setDay();
int setYear();
};
int Date::setMonth(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the month: ";
cin >> month;
if (month < 1) {
cout << "Please input a valid month";
}
else if (month > 12){
cout << "Please input a valid month";
}
else{
break;
}
}
return month;
}
int Date::setDay(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the day: ";
cin >> day;
if (day < 1) {
cout << "Please input a valid day";
}
else if ((month == 1 || 3 || 5 || 7 || 8 || 10 || 12) && (day > 31)){
cout << "Please input a valid day";
}
else if ((month == 4 || 6 || 9 || 11) && (day > 30)){
cout << "Please input a valid day";
}
else if ((month == 2) && (day > 28)){
cout << "Please input a valid day";
}
else{
break;
}
}
return day;
}
int Date::setYear(){
int i;
for (i=1; i!=0; i=1)
{
cout << "\n Input the year: ";
cin >> year;
if (year < 1) {
cout << "Please input a valid year";
}
else if (year > 2021){
cout << "Please input a valid year";
}
else{
break;
}
}
return year;
}
int Date::getMonth(){
int month;
return month;
}
int Date::getDay(){
int day;
return day;
}
int Date::getYear(){
int year;
return year;
}
void displayDate(int d,int m, int y){
cout << "Date: " <<m;
cout << "/" <<d;
cout << "/" <<y;
}
main(){
Date x;
int m,d,y;
x.setMonth();
x.setDay();
x.setYear();
m = x.getMonth();
d = x.getDay();
y = x.getYear();
displayDate(d, m ,y);
}
In your code, the getter is not returning the class member variables rather the local variables delared.
int Date::getMonth(){
return month;
}
int Date::getDay(){
return day;
}
int Date::getYear(){
return year;
}
Make the getters like this to return the actual member value.
int Date::getYear(){
int year;
return year;
}
In here, you declare a new int year; variable, that is not initialized, then you return that variable instead of the member variable of your class.
Change it to
int Date::getYear(){
return year;
}
Similar for your other get() functions.
Your conditions are also not working as you want it to:
(month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
doesn't compare month to all those numbers, the numbers just all evaluate to true. The condtion should be:
(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
I have tried to fix a number of problems in your code. And I have added comments explaining why:
#include <iostream>
// using namespace std; // avoid it if you can. It brings too many symbol in main workspace
using std::cout;
using std::cin;
void displayDate();
class Date{
private: // attributes should be private, only accessors should be public (encapsulation)
int month;
int day;
int year;
//int mmax; // comment out member that the code does not (still) use
//functions
public:
int getMonth();
int getDay();
int getYear();
int readMonth(); // setMonth should be a setter: int setMonth(int month) { this->month = month;}
int readDay();
int readYear();
};
int Date::readMonth(){
for (;;) // idiomatic form for an endless loop
{
cout << "\n Input the month: ";
cin >> month;
if (month < 1) {
cout << "Please input a valid month";
}
else if (month > 12){
cout << "Please input a valid month";
}
else{
break;
}
}
return month;
}
int Date::readDay(){
for (;;)
{
cout << "\n Input the day: ";
cin >> day;
if (day < 1) {
cout << "Please input a valid day";
}
else if (day > 31){ // other conditions were useless
cout << "Please input a valid day";
}
else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day > 30)){ // fix
cout << "Please input a valid day";
}
else if ((month == 2) && (day > 28)){
cout << "Please input a valid day";
}
else{
break;
}
}
return day;
}
int Date::readYear(){
for (;;)
{
cout << "\n Input the year: ";
cin >> year;
if (year < 1) {
cout << "Please input a valid year";
}
else if (year > 2021){
cout << "Please input a valid year";
}
else{
break;
}
}
return year;
}
int Date::getMonth(){
//int month; // the local variable would hide the member
return month;
}
int Date::getDay(){
//int day;
return day;
}
int Date::getYear(){
//int year;
return year;
}
void displayDate(int d,int m, int y){
cout << "Date: " <<m;
cout << "/" <<d;
cout << "/" <<y;
cout << '\n'; // do not forget end of lines
}
int main(){ // main shall be declared to return int
Date x;
int m,d,y;
x.readMonth();
x.readDay();
x.readYear();
m = x.getMonth();
d = x.getDay();
y = x.getYear();
displayDate(d, m ,y);
return 0; // better to be explicit
}
Other things could be improved, because re-usability is important in OOP. But I am too lazy to go further today ;-)

Testing a class using for loop in int main

In my main I have to test the class i made with a for loop but am a little stuck. I have to loop through 3 times and get user input for the ticketing system. I tried making an array and storing the user input but nothing I have tried so far has worked. Im trying to call upon the SetWorkTicket with my loop.
#include<iostream>
#include<iomanip>
#include<stdexcept>
#include<sstream>
using namespace std;
// start of the WorkTicket class
class WorkTicket{
public:
// defailt constructors, if the parameters are not specified the ticket will be set to 0 and the date to 1/1/2000. The rest empty strings
WorkTicket() : myTicketNumber(0), myClientId(""), myDay (1), myMonth (1), myYear(2000), myDescription ("") { }
WorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description);
// mutator method that sets all attributes of the object to the parameters as long as valid. If no problems are being detected set TRUE if not then FALSE.....
bool SetWorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description);
// accessor method that will show all the attributes of the ticket in the console menu
void ShowWorkTicket() const;
// here are the sets and gets for the attributes
// ticket number
void SetTicketNumber(int ticketNumber);
int GetTicketNumber() const {return myTicketNumber;}
// client id
void SetClientId(string clientId) {myClientId = clientId;}
string GetClientId() const { return myClientId;}
// date by day
void SetDay(int day);
int GetDay() const { return myDay; }
// date by month
void SetMonth(int month);
int GetMonth() const { return myMonth; }
// date by year
void SetYear(int year);
int GetYear() const { return myYear; }
// description
void SetDescription(string description) { myDescription = description; }
string GetDescription() const { return myDescription; }
private:
int myTicketNumber;
string myClientId;
int myDay;
int myMonth;
int myYear;
string myDescription;
};
// the work ticket constructor definition
WorkTicket::WorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description)
{
SetTicketNumber(ticketNumber);
SetClientId(clientId);
SetMonth(month);
SetDay(day);
SetYear(year);
SetDescription(description);
}
// set work ticket
bool WorkTicket::SetWorkTicket(int ticketNumber, string clientId, int month, int day, int year, string description)
{
const int MAX_DAY = 31; // setting max day to 31
const int MAX_MONTH = 12; // max month to 12
const int MIN_YEAR = 2000; // the min year 2000 as specified
const int MAX_YEAR = 2099; // max year 2099 as speciified
bool valid = true;
// setting the limits
if(ticketNumber < 0 || month < 1 || month > MAX_MONTH ||
day < 1 || day > MAX_DAY ||
year < MIN_YEAR || year > MAX_YEAR)
valid = false;
else if (clientId.length() < 1 || description.length() < 1)
valid = false;
else
{
myTicketNumber = ticketNumber;
myClientId = clientId;
myDay = day;
myMonth = month;
myYear = year;
myDescription = description;
}
return valid;
}
// this is to show the work ticket, it will show everything in the console..
void WorkTicket::ShowWorkTicket() const
{
cout << "\nWork Ticket Number: " << myTicketNumber
<< "\nClient ID: " << myClientId
<< "\nDate: " << setw(2) << setfill('0') << myMonth
<< "/" << setw(2) << setfill('0') << myDay
<< "/" << myYear
<< "\nIssue: " << myDescription << endl;
}
void WorkTicket::SetTicketNumber(int ticketNumber)
{
if(ticketNumber > 0)
{
myTicketNumber = ticketNumber;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetDay definition
void WorkTicket::SetDay(int day)
{
const int MIN_VALID = 1;
const int MAX_VALID = 31;
if(day >= MIN_VALID && day <= MAX_VALID)
{
myDay = day;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetMonth definition
void WorkTicket::SetMonth(int month)
{
const int MIN_VALID = 1;
const int MAX_VALID = 12;
if(month >= MIN_VALID && month <= MAX_VALID)
{
myMonth = month;
}
else
{
throw invalid_argument("Try Again.");
}
}
// WorkTicket::SetYear definition
void WorkTicket::SetYear(int year)
{
const int MIN_VALID = 2000;
const int MAX_VALID = 2099;
if(year >= MIN_VALID && year <= MAX_VALID)
{
myYear = year;
}
else
{
throw invalid_argument("Try Again.");
}
}
int main()
{
const int NUMBER_OF_TICKETS = 3;
WorkTicket tickets[NUMBER_OF_TICKETS];
int ticketNumber;
string clientId;
int day;
int month;
int year;
string description;
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "\WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cout << "Enter the client ID: " << endl;
getline(cin, clientId);
day = SetDay("Enter a day number: ");
}
}
Gather the input and then construct a WorkTicket. Push the tickets into a vector. In the code yet to be written, the newly create WorkTickets can be tested for correctness.
Make sure to include vector at the top of the file.
int main()
{
const int NUMBER_OF_TICKETS = 3;
int ticketNumber;
string clientId;
int day;
int month;
int year;
string description;
std::vector<WorkTicket> tickets;
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cin>> ticketNumber;
cout << "Enter the client ID: " << endl;
cin >> clientId;
cout << "Enter a day number: " << endl;
cin >> day;
cout << "Enter a month number: " << endl;
cin>> month;
cout << "Enter a year number: " << endl;
cin>> year;
cout << "Enter a description : " << endl;
cin >> description;
try {
tickets.push_back({ticketNumber, clientId, month, day, year, description});
}
catch(std::exception e)
{
std::cout << e.what() << std::endl;
}
}
}
Assuming the rest of your code works correctly and you only have problems in the main:
There are a few issues as commented by others in your code in main:
1) You declared WorkTicket tickets[NUMBER_OF_TICKETS]; but have not used it anywhere.
2) The variable tickets is an array and therefore in the for loop tickets[i] is of type WorkTicket.
3) SetDay is a member function of WorkTicket and takes int as argument.
In light of these, following changes made:
for (int i = 0; i <NUMBER_OF_TICKETS; i++)
{
cout << "\WorkTicket [" << i << "]: " << endl;
cout << "Enter the ticket number: " << endl;
cout << "Enter the client ID: " << endl;
getline(cin, clientId);
cout<<"Enter a day number:";
int day;
cin>>day;
tickets[i].SetDay(day); //day is int and tickets[i] is of WorkTicket
}
Hope this helps to understand the main part better.

C++ Age Calculator - Most Efficient Equations for Finding Time Between 2 Dates

I am trying to create an age calculator in C++ which takes user input for the current month, day, and year, along with the user's birthday, (MM DD YYYY). The rest of the functions are working properly, but I'm having issues with my calculateAge() function.
Can anybody see the problems with my equations in my calculateAge() function, or a way I could make this more efficient?
EDIT: Full Code
#include <iostream>
using namespace std;
main () {
//declare local variables
bool valid, validBirthday;
int cmonth, cday, cyear;
int bmonth, bday, byear;
int ageYears, ageMonths, ageDays;
char answer;
const int MAXGUESSES = 3;
//function declarations
bool enterDate (int&, int&, int&, const int);
bool enterBirthDate (int, int, int, int&, int&, int&, const int);
void calculateAge (int, int, int, int, int, int, int&, int&, int&);
//prompt the user for todays date and invoke the enterDate() function
cout << "Please enter today's date, ";
valid = enterDate(cmonth, cday, cyear, MAXGUESSES);
//if validDate() function doesn't recognize a valid date after three tries
//the user is alerted
if (valid == false)
cout << endl;
else
//if the date was valid show the user the date they entered and ask
//if they would like to calculate their age.
if (valid == true) {
cout << "Date entered is: " << cmonth << '/' << cday << '/' << cyear << endl;
cout << "Would you like to see how old you are? (y/n) ";
cin >> answer;
if (answer == 'N' || answer == 'n')
cout << "OK" << endl;
else
//if the user would like to see their age, call the enterBirthDate
//function and assign the return value to the boolean variable
//validBirthDate
if (answer == 'Y' || answer == 'y') {
if (validBirthday = enterBirthDate (cmonth, cday, cyear, bmonth, bday, byear, MAXGUESSES) == true) {
cout << "Date entered is: " << bmonth << '/' << bday << '/' << byear << endl;
//call the calculateAge() function to calculate the user's age
calculateAge(bmonth, bday, byear, cmonth, cday, cyear, ageYears, ageMonths, ageDays);
//display results
cout << "You are " << ageYears << " years, " << ageMonths << " months, and " << ageDays << " days old." << endl;
//display a special result if it is the users birthday
if (bmonth == cmonth && bday == cday)
cout << "Happy Birthday!" << endl;
}
else
cout << "You have entered an invalid birth day." << endl;
} //end if answer is yes
else //if answe is not yes or no
cout << "You did not enter 'y' or 'n'" << endl;
} //end if current date is valid
}
Functions
#include <iostream>
using namespace std;
//function definition for enterDate() - the function that prompts
//the user for input and parses input into months, days, and years
//and then calls the validDate() function to make sure the entered
//date is valid.
bool enterDate (int&month, int&day, int&year, const int MAXGUESSES) {
bool valid;
int counter = 1;
bool validDate(int&, int&, int&);
cout << "Please enter the date as MM DD YYYY: ";
cin >> month >> day >> year;
valid = validDate(month, day, year);
// use the constant MAXGUESSES and the variable counter to
// allow the user only three tries to enter a valid date
if (valid == false) {
while (valid == false && counter < MAXGUESSES) {
counter++;
cout << "The entered date is invalid, please re-enter: ";
cin >> month >> day >> year;
valid = validDate(month, day, year);
}
// if the user reaches the limit of three guesses, alert them
// and bring an end to the program
cout << "You have reached the limit for invalid dates." << endl;
}
return(valid);
}
// function definition for enterBirthDate() which prompts the user to enter
// their birthdate and invokes the enterDate() function to parse the input and
// the dateBefore() function to make sure the entered birth date occurs before
// the current date entered by the user
bool enterBirthDate (int cmonth, int cday, int cyear, int&bmonth, int&bday, int&byear, const int MAXGUESSES) {
bool valid;
bool valid2;
bool dateBefore (int, int, int, int, int, int);
bool enterDate (int&, int&, int&, const int);
cout << "We need to know your date of birth, ";
// call function enterDate() to prompt the user for input and parse
// the input into b(irthday)month, bday, and byear
valid = enterDate(bmonth, bday, byear, MAXGUESSES);
//if the birth date entered by the user is a valid date, make sure
//that the birth date occurs before the current date supplied by
//the user in enterDate()
if (valid == true)
valid2 = dateBefore(cmonth, cday, cyear, bmonth, bday, byear);
return(valid2);
}
//function definition for dateBefore() (invoked by enterBirthDate() which
//compares variables c(urrent)month cday, and cyear to b(irth)month, bday,
//and byear to make sure the birthday occurs before the current date supplied by the user
bool dateBefore (int cmonth, int cday, int cyear, int bmonth, int bday, int byear) {
bool valid;
//if the birth year is greater than the current year assign the boolean
//variable 0 (false) to valid, indicating an invalid birth date
if (byear > cyear)
valid = false;
else
//if birth year is equal to the current year, perform relational operations
//on the bmonth and cmonth variables to determine which date occured first
if (byear == cyear) {
//if the birth year and current year are the same, but the birth
//month is less than the current month, assign the value of true
//to the boolean variable valid
if (bmonth < cmonth)
valid = true;
else
//if the bmonth = cmonth perform relational operations on bday and cday
if (bmonth == cmonth)
//if the bday is less than the cday assign true to the boolean variable valid
if (bday < cday)
valid = true;
else
//if the bday is greater than the cday assign the value false to valid
valid = false;
else
//if bmonth is greater than the cmonth and byear is equal to the cyear
//assign false to valid, indicating an invalid birth day
if (bmonth > cmonth)
valid = false;
else
//if the cyear is greater than the byear assign the value of false to valid
if (byear < cyear)
valid = false;
}
return(valid);
}
//function definition for validDate() (invoked by enterDate() ) which uses variables of day, month, and year
//to make sure that the date entered is valid based on month, day, and year variables
bool validDate (int&month, int&day, int&year) {
//local variables
bool valid;
int maxDay;
//function declaration
int getLastDay (int);
//calculate maximum day based on month
maxDay = getLastDay(month);
//if the month is less than zero or greater than 12 assign the value false to
//the boolean variable valid indicating an invalid date
if (month < 0 || month > 12)
valid = false;
else
//if the month is valid make sure that the day falls inbetween 1 and the maximum day
//associated with the month entered
if (month > 0 && month <= 12) {
if (day > 0 && day <= maxDay)
valid = true;
else
valid = false;
}
return (valid);
}
//function definition for calculareAge(). Invoked by main(), calculate age accept parameters bmonth, bday, byear,
//cmonth, cday, and cyear (by value) to perform calculations and relational operations to determine age. The parameters
//ageYears, ageMonths, and ageDays are passed by reference so they can be output in the main() program.
void calculateAge (int bmonth, int bday, int byear, int cmonth, int cday, int cyear, int&ageYears, int&ageMonths, int&ageDays) {
//local variable
int maxDay;
//function declaration
int getLastDay (int);
maxDay = getLastDay (bmonth);
if (cyear >= byear && cmonth >= bmonth && cday >= bday){
ageYears = cyear - byear;
ageMonths = cmonth - bmonth;
ageDays = cday - bday;
}
else
if (cyear > byear) {
if (cmonth >= bmonth) {
if (cday < bday) {
ageYears = cyear - byear;
ageMonths = cmonth - bmonth - 1;
ageDays = maxDay - bday + cday;
}
}
else
if (cmonth < bmonth) {
if (cday > bday) {
ageYears = cyear - byear - 1;
ageMonths = 12 - bmonth + cmonth;
ageDays = cday - bday;
}
else
if (bday > cday) {
ageYears = cyear - byear - 1;
ageMonths = 12 - bmonth + cmonth - 1;
ageDays = maxDay - bday + cday;
}
}
}
}
//function definition for getLastDay(), uses the month entered to calculate the maximum
//valid day for that month
int getLastDay (int month) {
int maxDay;
switch (month) {
case 4:
case 6:
case 9:
case 11:
maxDay = 30;
break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
maxDay = 31;
break;
case 2:
maxDay = 28;
}
return(maxDay);
}
Well, it seems your code just fails in cases like: 1 9 2001 y 1 10 2000.
What about giving a constant value for each day of the calendar?
I modified your calculateAge() function and created another function named getInt() which gives the corresponding constant value of a date.
So, deducting two dates easily gives us the result. See the code below to be clear.
Feel free to ask anything about it.
New getInt function:
int getInt(int y, int m, int d)
{
int ret = y*365;
//function declaration
int getLastDay (int);
for (int i = 1; i<m; i++)
ret+=getLastDay(i);
ret+=d;
return ret;
}
Modified calculateAge function:
//function definition for calculareAge(). Invoked by main(), calculate age accept parameters bmonth, bday, byear,
//cmonth, cday, and cyear (by value) to perform calculations and relational operations to determine age. The parameters
//ageYears, ageMonths, and ageDays are passed by reference so they can be output in the main() program.
void calculateAge (int bmonth, int bday, int byear, int cmonth, int cday, int cyear, int&ageYears, int&ageMonths, int&ageDays) {
//local variable
int maxDay;
//function declaration
int getLastDay (int);
int now = getInt(cyear,cmonth,cday);
int birthday = getInt(byear,bmonth,bday);
if(now<birthday) return;
int diff = now-birthday;
ageYears = (diff)/365;
diff-=(365*ageYears);
ageMonths = 0;
int rest;
while(1)
{
rest = getLastDay(ageMonths+1);
if(diff>=rest)
{
diff-=rest;
ageMonths++;
}
else break;
}
ageDays = diff;
}

Date Struct is not properly being checked

I have some C++ code:
#include <bjarne/std_lib_facilities.h>
struct Date {
int month;
int day;
int year;
};
Date get_date();
Date get_birth_date();
int days_in_month (int month);
bool is_valid_date (const Date& date);
bool is_before (const Date& date1, const Date& date2);
int main()
{
cout << "Welcome to Age Calculator!\n";
Date current;
current = get_date();
cout << "Would you like to see how old you are (y/n)?";
char answer, slash;
cin >> answer;
Date birthday;
if(answer == 'y'){
birthday = get_birth_date();
bool valid = is_valid_date (birthday);
bool before = is_before (current,birthday);
while(!valid && !before){
cout << "Invalid birth date? Please re-enter: ";
cin >> birthday.month >> slash >> birthday.day >> slash >> birthday.year;
valid = is_valid_date (birthday);
before = is_before (current,birthday);
}
cout << "Your birthday is: " << birthday.month << "/" << birthday.day << "/" << birthday.year << "\n";
}
else
cout << "You are so chicken! \n";
}
Date get_date()
{
cout << "Please enter today's date (mm/dd/yyyy): ";
Date today;
char slash;
cin >> today.month >> slash >> today.day >> slash >> today.year;
bool valid = is_valid_date (today);
while(!valid){
cout << "Invalid date? Please re-enter: ";
cin >> today.month >> slash >> today.day >> slash >> today.year;
valid = is_valid_date (today);
}
cout << "Date entered was: " << today.month << "/" << today.day << "/" << today.year << "\n";
return today;
}
Date get_birth_date()
{
cout << "Please enter your birth date (mm/dd/yyyy): ";
Date birth;
char slash;
cin >> birth.month >> slash >> birth.day >> slash >> birth.year;
return birth;
}
int days_in_month (int month)
{
int month31[7] = {1,3,5,7,8,10,12};
for(int i = 0; i < 7; i++){
if(month == month31[i])
return 31;
}
int month30[4] = {4,6,9,11};
for(int i = 0; i < 4; i++){
if(month == month30[i])
return 30;
}
if(month == 2)
return 28;
}
bool is_valid_date (const Date& date)
{
int months[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
int days = 0;
for(int i = 0; i < 12; i++){
if(date.month == months[i]){
days = days_in_month (date.month);
if(date.day <= days && date.day > 1){
return true;
}
}
return false;
}
bool is_before (const Date& date1, const Date& date2)
{
cout << date1.day << " " << date2.day;
if(date2.year < date1.year){
return true;
}
else if(date2.year == date1.year)
{
cout << "-";
if(date2.month < date1.month)
return true;
else if(date2.month == date1.month){
if(date2.day <= date1.day)
return true;
}
else
return false;
}
return false;
}
I know that the is_valid_date function works, but when I'm testing a birthday that comes after the current day entered, for some reason, it passes the is_before test and never goes to the while loop asking the user to enter a valid birthday. Any suggestions would be greatly appreciated! Thanks in advance!
Edit: The specific inputs that I'm testing are: for today's date, I enter 05/06/2015 and for a birthday, I enter 05/07/2015. It then prints the birthday, which means it skips the while loop in int main(), which it shouldn't do, since the birthday comes after the current date.
Your condition is wrong:
while(!valid && !before)
Your condition tries to get a new birthday if the one entered is invalid and is after the current date. I think you want:
while(!valid || !before)
Which gets a new birthday if the one entered is invalid or is after the current date.
You should change while(!valid && !before) to while(!valid || !before).
You want to stay in the loop as long as the birth date is invalid or the birth date is after the current date. Currently, if you enter a valid date which is after the current date, it will break out of the loop because the first condition is false (the date is valid).