Ok, I have a program that uses three classes and a driver program, all compiled separately. One class is a Date class. The Date class header looks like this:

#ifndef DATE_H
#define DATE_H

#include <iostream>

using namespace std;

class Date {
   public:
      // initializers
      Date();
      Date(int day, int month, int year);

      // Accessors
      int day() const;
      int month() const;
      int year() const;
  
      // Date::valid returns true if the host object is a valid date.
      bool valid() const;

      // Comparison functions, to be used by overloaded operators
      bool equal(const Date&) const;
      bool earlierThan(const Date&) const;
  
      //IO functions uses overloaded operators to process data.
      void input(istream&);
      void output(ostream&) const;
   private:
      static bool checkDate(int d, int m, int y);
      int _day, _month, _year;
};

// IO operators
istream& operator>>(istream&, Date&);
ostream& operator<<(ostream&, const Date&);

// Comparison operators
bool operator==(const Date&, const Date&);
bool operator!=(const Date&, const Date&);
bool operator<(const Date&, const Date&);
bool operator<=(const Date&, const Date&);
bool operator>(const Date&, const Date&);
bool operator>=(const Date&, const Date&);

#endif

Here is the code for the constructors, as well as the code for the Date::valid function:

Constructors:

Date::Date() {
   _day = 1;
   _month = 1;
   _year = 2000;
}

Date::Date(int day, int month, int year) {
   if (checkDate(day, month, year)) {
      _day = day;
      _month = month;
      _year = year;
   }
   else {
   _day = 31;
   _month = 12;
   _year = 1999;
   }
}

The following is checkDate, it checks to make sure that the date is a valid date after the year 2000. In the driver program(further down the post) when Date::valid() is ran, all it does is run this function because this function is private, so Date::valid() would be the accessor for this private function I guess:

bool Date::checkDate(int d, int m, int y) {
   // check year range
   if (y < 2000) 
      return false;

   // Determine if leap year
   bool leapYear = false;

   // All years evenly divisible by 400 are leap.
   // All other years evenly divisible by 4 are leap
   // except those that are evenly divisible by 100.
   if ((y % 400) == 0) 
      leapYear = true;
   else if ((y % 4 == 0) && !(y % 100 == 0))
      leapYear = true;

   // Month check
   if (m < 1 || m > 12) return false;

   // Day check
   const int nMonths = 12;
   const int nDays[nMonths] = {31,28,31,30,31,30,31,31,30,31,30,31};

   // Handle Feb 29
   if (leapYear && m == 2 && d == 29) 
      return true;

   // Handle all other days
   if (d < 1 || d > nDays[m-1]) 
       return false;

   // If it reaches this point, the date is OK
   return true;
}

Ok, now my problem. This is what I need a faulty date entered to look like in output:

-Enter your departure date (MM/DD/YYYY) : 08/32/2008
-ERROR: "8/32/2008" is not a valid date.

-Enter your departure date (MM/DD/YYYY) : 02/29/2007
-ERROR: "2/29/2007" is not a valid date.

-Enter your departure date (MM/DD/YYYY) : 02/29/2008
-Enter your return date (MM/DD/YYYY) :

But this is what it looks like:

-Enter your departure date (MM/DD/YYYY) : 08/32/2008
-ERROR: "12/31/1999" is not a valid date.
-
-Enter your departure date (MM/DD/YYYY) : 02/29/2007
-ERROR: "12/31/1999" is not a valid date.
-
-Enter your departure date (MM/DD/YYYY) : 02/29/2008
-Enter your return date (MM/DD/YYYY) :

Because if an invalid date is entered the Date Class automatically stores 12/31/1999 instead of whatever was entered.

WITHOUT CHANGING THE DATE CLASS AT ALL! How can I fix it so it outputs the date entered by the user when there is an error? I'm sure its something really simple, but I can't figure it out.

Here is this part of the driver program, obviously "flag" is a boolean array:

while(flag[2]) {
   cout << "\nEnter your departure date (MM/DD/YYYY) : ";
   cin  >> d1;
   if (d1.valid())
      flag[2] = false;
   if (flag[2])
      cout << "ERROR: \"" << d1 << "\" is not a valid date.\n";
}

while(flag[3]) {
   cout << "Enter your return date    (MM/DD/YYYY) : ";
   cin  >> d2;
   if (d2.valid())
      flag[3] = false;
   if (!(d2.valid()))
      cout << "ERROR: \"" << d2 << "\" is not a valid date.\n";
   else if (d2 < d1) {
      cout << "ERROR: Return date is before departure date.\n";
      flag[3] = true;
   }
   else if (d1 == d2) {
      cout << "WARNING: Your departure date and return date "
           << "are the same.\nWas this your intent? (Y or N) : ";
      cin  >> choice;
      if ((choice == 'Y') || (choice == 'y'))
         flag[3] = false;
      else if ((choice == 'N') || (choice == 'n'))
         flag[3] = true;
      else {
         cout << "A fatal error has occured.\n - Program Terminated -\n";
         return 1;
      }
   }
}

Thanks for any help you can give.

Recommended Answers

All 3 Replies

>How can I fix it so it outputs the date entered by the user when there is an error?
You're printing the value of the date itself in your error message. At that point, the date has already been checked, errored, and set to the default. Unfortunately, I can't tell you how to fix the problem without changing the Date class, because I don't know how the Date class works.

I can't change the Date class because its for an assignment and we were given the class, and told we couldn't alter it. Date.h is in the post above. Here's Date.cpp:

#include "Date.h"

Date::Date() : _day(1), _month(1), _year(2000) {}

Date::Date(int day, int month, int year) : _day(12), _month(31), _year(1999) {
    if (checkDate(day, month, year)) {
        _day = day;
        _month = month;
        _year = year;
    }
}

// Accessors
int Date::day() const { return _day; }
int Date::month() const { return _month; }
int Date::year() const { return _year; }

bool Date::valid() const {
    return checkDate(_day, _month, _year);
}

// Comparison functions, to be used by overloaded operators
bool Date::equal(const Date& d2) const {
    return ( _day == d2._day && _month == d2._month && _year == d2._year);
}

bool Date::earlierThan(const Date& d2) const {
    if (_year < d2._year) return true;
    else if (_year == d2._year)
        if (_month < d2._month) return true;
        else if (_month == d2._month && _day < d2._day) return true;
    return false;
}

// Input/output functions, also to be used by overloaded operators
// Date format is DD/MM/YYYY
        
void Date::input(istream& is) {
    int d, m, y;
    char c;
    is >> m  >> c >> d >> c >> y;
    if (checkDate(d, m, y)) {
        _day = d;
        _month = m;
        _year = y;
    }
    else {
        _day = 31;
        _month = 12;
        _year = 1999;
    }
}

void Date::output(ostream& os) const {
    os  << _month << "/" << _day << "/" << _year;
}

bool Date::checkDate(int d, int m, int y) {    // check year range
    if (y < 2000) return false;

    // Determine if leap year
    bool leapYear = false;
    // All years evenly divisible by 400 are leap.
    // All other years evenly divisible by 4 are leap
    // except those that are evenly divisible by 100.
    if ((y % 400) == 0) leapYear = true;
    else if ((y % 4 == 0) && !(y % 100 == 0))
        leapYear = true;

    // Month check
    if (m < 1 || m > 12) return false;

    // Day check
    const int nMonths = 12;
    const int nDays[nMonths] = {31,28,31,30,31,30,31,31,30,31,30,31};

    // Handle Feb 29
    if (leapYear && m == 2 && d == 29) return true;

    // Handle all other dates
    if (d < 1 || d > nDays[m-1]) return false;

    // If we reach this point, the date is OK
    return true;
}

istream& operator>>(istream& is, Date& d) {
    d.input(is);
    return is;
}

ostream& operator<<(ostream& os, const Date& d) {
    d.output(os);
    return os;
}

bool operator==(const Date& d1, const Date& d2) {
    return d1.equal(d2);
}

bool operator!=(const Date& d1, const Date& d2) {
    return !d1.equal(d2);
}

bool operator<(const Date& d1, const Date& d2) {
    return d1.earlierThan(d2);
}

bool operator<=(const Date& d1, const Date& d2) {
    return (d1.earlierThan(d2) || d1.equal(d2));
}

bool operator>(const Date& d1, const Date& d2) {
    return d2.earlierThan(d1);
}

bool operator>=(const Date& d1, const Date& d2) {
    return (d2.earlierThan(d1) || d2.equal(d1));
}
int y, d, m;
char c;

while(flag[2]) 
{   
   cout << "\nEnter your departure date (MM/DD/YYYY) : ";
   cin >> m >> c >> d >> c >>  y;
   Date d1(d, m, y);
   if(d1.year() == 1999)
     cout << "ERROR: \"" << m << c << d << c << y << "\" is not a valid date.\n";
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.