Reputation: 13
Here's a function I wrote that first checks whether a date is valid, then works out the date a day after that. To simplify things, leap years don't apply in this program.
#include <iostream>
using namespace std;
// Declaration of Date class
class Date {
public:
int year;
int month;
int day;
};
bool valid_date(Date &today);
bool getTomorrow(Date today, Date &tomorrow);
int main() {
Date today, tomorrow;
today.year=2015;
today.month=2;
today.day=28;
bool getTomorrow(today, tomorrow);
}
bool valid_date(Date &today) {
bool valid = true;
const int days[12] = {
31,28,31,30,31,30,31,31,30,31,30,31
};
if (today.month<1 || today.month > 12) {
valid = false;
}
else if (today.day <1 || today.day > days[today.month-1]) {
valid = false;
}
return valid;
}
bool getTomorrow(Date today, Date &tomorrow) {
bool valid = true;
const int days[12] = {
31,28,31,30,31,30,31,31,30,31,30,31
};
if (valid_date(today)==false) {
valid = false;
}
else if (today.day==31 && today.month==12) {
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year= today.year +1;
}
else if (today.day == days[today.month-1]) {
tomorrow.day = 1;
tomorrow.month = today.month +1;
tomorrow.year = today.year;
}
else {
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year= today.year;
}
return valid;
}
It fails to run and Xcode gives me this warning 'excess elements in scalar initialiser' for this line:
bool getTomorrow(today, tomorrow);
Any help much appreciated!
Upvotes: 1
Views: 4335
Reputation: 881403
A statement like:
int xyzzy(42);
is a way to initialise the variable to a given value. This is what's happening with your code:
bool getTomorrow(today, tomorrow);
except the compiler is complaining about you providing two values for the initialiser.
The correct way to call it is with something like:
bool myBoolVar = getTomorrow(today, tomorrow);
And, in the interest of offering advice, I'm not a big fan of the "only one return point" guideline, especially when it makes your code longer and more prone to error. In that sense, valid_date()
could be written much more succinctly, including breaking out the days[]
array since it's used in multiple places and is never subject to change:
static const int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
bool valid_date (Date today) {
// Check month first.
if (today.month < 1 || today.month > 12)
return false;
// Allow Feb 29 in leap year if needed.
if (today.month == 2 && today.day == 29) {
if (today.year % 400 == 0)
return true;
if ((today.year % 4 == 0) && (today.year % 100 != 0))
return true;
}
// Then check day.
if (today.day < 1 || today.day > days[today.month-1])
return false;
return true;
}
And the code for getting tomorrow also seems a little tortured for the same reason, so I'd be looking at something like:
bool getTomorrow (Date today, Date &tomorrow) {
// Don't do anything for bad dates.
if (!valid_date (today)) return false;
// Just blindly add a day with no checks.
tomorrow.year = today.year;
tomorrow.month = today.month;
tomorrow.day = today.day + 1;
// Allow Feb 29 in leap year if needed.
if (tomorrow.month == 2 && tomorrow.day == 29) {
if (tomorrow.year % 400 == 0)
return true;
if ((tomorrow.year % 4 == 0) && (tomorrow.year % 100 != 0))
return true;
}
// Catch rolling into new month.
if (tomorrow.day > days[tomorrow.month-1]) {
tomorrow.day = 1;
tomorrow.month++;
// Catch rolling into new year.
if (tomorrow.month == 13) {
tomorrow.month = 1;
tomorrow.year++;
}
}
return true;
}
You'll notice I've also put in code (in both functions) to actually allow for February 29 in leap years, based on the rule that multiples of 400, and multiples of 4 that aren't also multiples of 100, are leap years. If it's not required, simply remove it - I'm just a stickler for completeness :-)
Upvotes: 5
Reputation: 797
That's not the correct syntax to call a function. Change bool getTomorrow(today, tomorrow);
to bool b = getTomorrow(today, tomorrow);
Upvotes: 2
Reputation: 308158
I think you meant:
bool variable = getTomorrow(today, tomorrow);
^^^^^^^^^^
Upvotes: 2