1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include <iostream>
#include <iomanip>
struct Date {
enum error_t { NO_ERROR = 0, INPUT_ERROR = 1, YEAR_ERROR = 2, MONTH_ERROR = 3, DAY_ERROR = 4 };
int year = 1900 ;
int month = 1 ;
int day = 1 ;
error_t errState = NO_ERROR ;
static error_t validate( int y, int m, int d )
{
// TO DO:
// return YEAR_ERROR if y is invalid
// return MONTH_ERROR if m is invalid
// return DAY_ERROR if d is invalid
return NO_ERROR ; // if y, m, d form a valid date
}
};
std::ostream& operator<< ( std::ostream& stm, const Date& dt ) {
if( dt.errState == Date::NO_ERROR ) {
const char old_fill = stm.fill() ;
return stm << std::setfill('0') << std::setw(4) << dt.year << '/' << std::setw(2)
<< dt.month << '/' << std::setw(2) << dt.day << std::setfill(old_fill) ;
}
else return stm << "<invalid date>" ;
}
// extract the next next non white space character in the stream
// return true if it is the expected separator '/', false otherwise
static bool valid_sep( std::istream& stm ) {
char separator ; // expected to be '/'
return stm >> separator && separator == '/' ;
}
std::istream& operator>> ( std::istream& stm, Date& dt ) {
int y, m, d ;
// if the input is of the form year/month/date ie. five fields
// year, '/', month, '/', day (white space is allowed between fields)
if( stm >> y && valid_sep(stm) && stm >> m && valid_sep(stm) && stm >> d ) {
const Date::error_t state = Date::validate( y, m, d ) ;
if( state == Date::NO_ERROR ) dt = { y, m, d, state } ; // update dt with the values that were read
else dt.errState = state ; // update only error state; leave everything else unchanged
}
// otherwise, update error state; leave everything else unchanged
else dt.errState = Date::INPUT_ERROR ;
return stm ;
}
|