hgst
hgst

Reputation: 13

C++ function that works out tomorrow's date give today's date

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

Answers (3)

paxdiablo
paxdiablo

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

mbgda
mbgda

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

Mark Ransom
Mark Ransom

Reputation: 308158

I think you meant:

bool variable = getTomorrow(today, tomorrow);
     ^^^^^^^^^^

Upvotes: 2

Related Questions