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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
|
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//The following are error condition definitions:
#define GOOD_DATE 0
#define INVALID_MONTH -1
#define INVALID_DAY -2
#define INVALID_YEAR -3
#define MISSING_DASH -4
#define MISSING_SECOND_DASH -5
#define TOO_MANY_DASHES -6
#define DASH_IN_WRONG_POSITION -7
#define BAD_MONTH_DIGIT -8
#define BAD_DAY_DIGIT -9
#define BAD_YEAR_DIGIT -10
#define MISSING_DIGITS_BETWEEN_DASHES -11
//The following are function prototypes:
bool isLeapYear(int year);
int getNumberOfDaysInMonth(int month, int year);
bool isGoodDayOfTheMonth(int month, int day, int year);
int checkValidDate(int month, int day, int year);
int checkDashes(string date, size_t &firstDash, size_t &secondDash);
int convertSubstringToNumber(string date, size_t firstPos, size_t secondPos);
int checkDigits(string date, size_t firstDash, size_t secondDash);
int extractDateComponents(string date, int &month, int &day, int &year);
int computeDayOfYear(int month, int day, int year);
int determineDayOfYear(string date);
void processFile();
void prinResults(string date);
int main()
{
processFile();
system("pause");
return 0;
}
bool isLeapYear(int year) /* Returns true if the specified year is a leap year; returns false otherwise. */
{
if(year % 4 == 0)
{
if (year % 100 != 0)
return true;
else if (year % 400 == 0)
return true;
}
else
return false;
}
int getNumberOfDaysInMonth(int month, int year) /* Returns the number of days in the specified month for the specified year. It is assumed these two values have already been validated as being a valid month (1 through 12) and year (non-negative). */
{
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: return 31;
break;
case 4:
case 6:
case 9:
case 11: return 30;
break;
case 2:
if (isLeapYear(year))
return 29;
else
return 28;
}
}
bool isGoodDayOfTheMonth(int month, int day, int year) /* Returns true if the specified day is a valid day of the specified month in the specified year; returns false otherwise.*/
{
if (day < 1 || day > getNumberOfDaysInMonth(month, year))
return false;
else
return true;
}
int checkValidDate(int month, int day, int year) /* returns GOOD_DATE if the specified month, day and year specify a valid date; otherwise returns INVALID_MONTH if the month is invalid, INVALID_DAY if the day is invalid and INVALID_YEAR if the year is invalid.*/
{
if (month < 1 || month > 12)
return INVALID_MONTH;
else if (!isGoodDayOfTheMonth(month, day, year))
return INVALID_DAY;
else if (year < 1)
return INVALID_YEAR;
else
return GOOD_DATE;
}
int checkDashes(string date, size_t &firstDash, size_t &secondDash) /* Determines whether the date string contains an appropriate set of dashes, e.g. passing “2-16-2011” in the date string would return GOOD_DATE.
The two size_t reference parameters are to be assigned the string position of the first and second dash, respectively.
Possible error returns are MISSING_DASH, MISSING_SECOND_DASH, TOO_MANY_DASHES and DASH_IN_WRONG_POSITION. */
{
firstDash = date.find_first_of('-');
if (firstDash == string::npos)
return MISSING_DASH;
else
secondDash = date.find_first_of('-', firstDash + 1);
if (secondDash == string::npos)
return MISSING_SECOND_DASH;
else
{
size_t thirdDash = date.find_first_of('-', secondDash + 1);
if (thirdDash != string::npos)
return TOO_MANY_DASHES;
else {
if (firstDash == secondDash)
return MISSING_DIGITS_BETWEEN_DASHES;
if (firstDash != 3 || secondDash != 6)
return DASH_IN_WRONG_POSITION;
}
}
return GOOD_DATE;
}
int convertSubstringToNumber(string date, size_t firstPos, size_t secondPos) /* Extracts the characters from the date string beginning at the location specified by firstPosition and continuing up through the locations specified by secondPosition to form an integer return value. It is assumed that the date string has already been validated, i.e. the postitions are valid and the substring’s characters are all numeric.*/
{
int convertedValue = 0;
for (size_t pos = firstPos; pos < secondPos; pos++)
{
char c = date.at(pos);
convertedValue = convertedValue * 10 + c - '0';
}
return convertedValue;
}
int checkDigits(string date, size_t firstDash, size_t secondDash) /* Uses the two locations in the date string as the bounds to check for strictly numeric characters. All three date components, month, day and year, are checked for validity.
Returns GOOD_DATE if they are all numeric, otherwise returns BAD_MONTH_DIGIT, BAD_DAY_DIGIT, or BAD_YEAR_DIGIT as appropriate.*/
{
for (size_t pos = 0; pos < firstDash; pos++)
{
if (!isdigit(date.at(pos)))
return BAD_MONTH_DIGIT;
}
for (size_t pos = firstDash + 1; pos < secondDash; pos++)
{
if (!isdigit(date.at(pos)))
return BAD_DAY_DIGIT;
}
for (size_t pos = secondDash + 1; pos < date.length(); pos++)
{
if (!isdigit(date.at(pos)))
return BAD_YEAR_DIGIT;
}
return GOOD_DATE;
}
int extractDateComponents(string date, int &month, int &day, int &year) /* Stores the month, day and year specified by the date parameter string into the three associated reference parameter integers.
This function should perform all of its work by calling functions already described. Functions checking for error conditions should be called in an appropriate order to avoid pasing unverified input to functions noted as assuming good input. Returns GOOD_DATE if successful, otherwise returns error values obtained from calling lower-level functions.*/
{
size_t firstDash, secondDash;
int returnValue = checkDashes(date, firstDash, secondDash);
if (returnValue == GOOD_DATE)
{
returnValue = checkDigits(date, firstDash, secondDash);
if (returnValue == GOOD_DATE)
{
month = convertSubstringToNumber(date, 0, firstDash);
day = convertSubstringToNumber(date, firstDash + 1, secondDash);
year = convertSubstringToNumber(date, secondDash + 1, date.length());
returnValue = checkValidDate(month, day, year);
}
}
return returnValue;
}
int computeDayOfYear(int month, int day, int year) /* Given the specified month, day and year, computes the number of the day in the year. It is assumed the three input parameters specify a valid date. This example was done in class.*/
{
int dayOfYear = 0;
for (int aMonth = 1; aMonth < month; aMonth++)
{
dayOfYear += getNumberOfDaysInMonth(aMonth, year);
}
return dayOfYear + day;
}
int determineDayOfYear(string date) /* Computes the day of the year for the specified date string. Returns that value if the date is valid; otherwise returns an error code indicating how the string was invalid. */
{
int month,day, year;
int returnValue;
returnValue = extractDateComponents(date, day, month, year);
if (returnValue == GOOD_DATE)
{
returnValue = computeDayOfYear(month, day, year);
}
return returnValue;
}
void printResults(string date)
{
if (determineDayOfYear(date) > 0)
cout << date << " is the " << determineDayOfYear(date) << " day of the year" << endl;
}
void processFile()
{
ifstream infile;
infile.open("dates.txt");
if (!infile)
cout << "Unable to open file!" << endl;
while (infile)
{
string date;
infile >> date;
printResults(date);
}
infile.close();
}
|