// File Name: calv2.cpp // Author: Xiannong Meng // Assignment: solution for homework // Date: Apr. 27, 1997 // Problem: this program reads an integer representing a year from keyboard // and prints the calendar for that year in a three-column format. // Note: Since this program is a translation from a C program, it is not // in a perfect C++ format. #include #include "calv2.h" // header file for calendar // Name: Calendar // Intent: constructor which initializes certain values // Precondition: none // Postcondition: a calendar object with initial values created Calendar::Calendar() { // since C++ does not allow initialization like this in class // header file, so we do it here. int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int daysLp[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int i; for (i = 0; i < NumMon; i ++) { daysInMonth[i] = days[i]; daysLpMonth[i] = daysLp[i]; } } // Name: PrintCalendar // Intent: take the parameter specifying the year to print, and print the // calendar. This should be the only public interface function // Precondition: A calendar object has been created, a year has been input // from keyboard. // Postcondition: A calendar is printed on screen in a three-column format void Calendar::PrintCalendar(int year) { // figure out and store days in array // each month can have upto 6 weeks int daysPerMon[NumMon][WkPerMon][DAYINWK]; int day; InitDays(daysPerMon); day = CalcFirstDay(year); // the next section calculates the values of days in each slot for (int i = 0; i < 12; i ++) { if (IsLeapYear(year) == false) CalcMonth(day, daysInMonth[i], daysPerMon[i]); else CalcMonth(day, daysLpMonth[i], daysPerMon[i]); } // then prints it cout << " " << year << endl; PrintYear(daysPerMon); } // Name: InitDays // Intent: initialize days to have the value of -1. When the calendar is // printed, if it has a value of 0, a space will be printed, otherwise print // its value. // Precondition: calendar object has been created // Postcondition: calendary initialized void Calendar::InitDays(int a[NumMon][WkPerMon][DAYINWK]) { for (int i = 0; i < NumMon; i ++) for (int j = 0; j < WkPerMon; j ++) for (int k = 0; k < DAYINWK; k ++) a[i][j][k] = -1; } // Name: CalcMonth // Intent: calcualte values in each day of each month // Precondition: days have been intialized // Postcondition: calendary is ready for print void Calendar::CalcMonth(int &whichDay, int dayInMonth, int daysValue[WkPerMon][DAYINWK]) { int leadDay = whichDay % DAYINWK; int day = 1; int i; int printDay, printWk; for (i = 0; i < leadDay; i ++) daysValue[0][i] = 0; for (i = day; i <= dayInMonth; i ++) { printDay = (day + leadDay - 1) % DAYINWK; printWk = (day + leadDay - 1) / DAYINWK; daysValue[printWk][printDay] = day; day ++; whichDay ++; } } // Name: PrintYear // Intent: After the values in each day have been filled, print the calendar // Precondition: day values have been filled (calculated) // Postcondition: calendary is printed void Calendar::PrintYear(int days[NumMon][WkPerMon][DAYINWK]) { // print one quarter at a time PrintQuarter(Jan, Mar, days); PrintQuarter(Apr, Jun, days); PrintQuarter(Jul, Sep, days); PrintQuarter(Oct, Dec, days); } // Name: PrintQuarter // Intent: print one quarter across the line (3 months) // Precondition: day values have been calculated // Postcondition: one quarter is printed void Calendar::PrintQuarter(Month a, Month b, int days[NumMon][WkPerMon][DAYINWK]) { cout << " "; PrintMonthHead(a); cout << " "; PrintMonthHead(Month((int)a + 1)); cout << " "; PrintMonthHead(Month((int)a + 2)); cout << endl; PrintWkHead(); cout << " "; PrintWkHead(); cout << " "; PrintWkHead(); cout << endl; PrintMonth(a, b, days); } // Name: PrintMonth // Intent: Print three month across the line, i.e. first week of the first // month, first week of the second month, first week of the third month, then // second week of the first month, second week of the second moenth, etc. // Precondition: The headers of the months and weeks have been printed // Postcondition: three months across the line have been printed void Calendar::PrintMonth(Month a, Month b, int days[NumMon][WkPerMon][DAYINWK]) { int j, k; Month i; for (j = 0; j < WkPerMon; j ++) { for (i = a; i <= b; i = Month((int)i + 1)) { for (k = 0; k < DAYINWK; k ++) { if (days[i][j][k] <= 0) cout << " "; else if (days[i][j][k] > 0) cout << setw(3) << days[i][j][k]; } if (i < b) cout << " "; } cout << endl; } } // Name: PrintMonthHead // Intent: Print the month header // Precondition: none // Postcondition: the name of a month is printed void Calendar::PrintMonthHead(int month) { switch (month+1) { case 1 : cout << "Jan"; break; case 2 : cout << "Feb"; break; case 3 : cout << "Mar"; break; case 4 : cout << "Apr"; break; case 5 : cout << "May"; break; case 6 : cout << "Jun"; break; case 7 : cout << "Jul"; break; case 8 : cout << "Aug"; break; case 9 : cout << "Sep"; break; case 10 : cout << "Oct"; break; case 11 : cout << "Nov"; break; case 12 : cout << "Dec"; } } // Name: PrintWkHead // Intent: Print the week header // Precondition: none // Postcondition: the names of seven weekdays are printed void Calendar::PrintWkHead() { cout << " S M Tu W Th F S"; } // Name: CalcFirstDay // Intent: // given the year and the first day in 1753 was a Monday // figure out which day falls on this year's first day // Precondition: the year is given // Postcondition: first day value is calculated int Calendar::CalcFirstDay(int thisYear) { // calculated how many days since 1753 (BASEYEAR) int days = 1; for (int year = BASEYEAR; year < thisYear; year ++) { if (IsLeapYear(year) == true) days = (days + 366) % DAYINWK; else days = (days + 365) % DAYINWK; } return days; } // Name: IsLeapYear // Intent: decide whether or not this is a leap year // Precondition: an integer value of year has been typed in // Postcondition: a true or false is returned bool Calendar::IsLeapYear(int y) { return (((y % 4 == 0) && (y % 100) != 0) || (y % 400 == 0)); }