Cal
January 1, 2010
Happy New Year! And best wishes for a healthy and prosperous year for all my readers and their families.
On the first day of a new year it seems appropriate to write an exercise based on calendars. Unix provides a cal
command to print calendars. There are several forms:
cal
— prints a calendar for the current monthcal
year — prints a twelve-month calendar for the specified year; note that year 10 occurred during the time of Christ, so you must specify 2010 for the current yearcal
month year — prints a calendar for the specified month and year; the month is given as a number from 1 to 12cal -3
— prints a three-month calendar for the prior month, current month and next month
The current date is highlighted wherever it appears.
Your task is to implement cal
. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
[…] today’s Programming Praxis exercise we have to implement the Unix utility cal, which prints calendars. […]
My Haskell solution (see http://bonsaicode.wordpress.com/2010/01/01/programming-praxis-cal/ for a version with comments):
There’s a bug here: compare the output of your cal with the standard one (either BSD or GNU) on September 1752 or any earlier date.
“Give us back our eleven days!”
C++ style
#include
#include
#include
using namespace std;
const int MONTHS_IN_YEAR = 12;
const int DAYS_IN_WEEK = 7;
const int MAX_DAYS_IN_MONTH = 31;
const int MIN_DAYS_IN_MONTH = 28;
const int LEAP_YEAR_FACTOR = 4;
const int DAY_WIDTH = 3;
const int JAN = 1;
const int FEB = 2;
const int MAR = 3;
const int APR = 4;
const int MAY = 5;
const int JUN = 6;
const int JUL = 7;
const int AUG = 8;
const int SEP = 9;
const int OCT = 10;
const int NOV = 11;
const int DEC = 12;
void PrintMonthHeader(int month);
string MonthString(int month);
void PrintMonthBody(int year, int month, int& day);
void PrintMonthDates(int& day, int lastday);
void PrintSelectedMonths(int year, int start_month,
int day, int total_months);
int main()
{
int month, totalMonths, startDay, year;
cout <> year;
while (year != 0)
{
cout <> month;
cout <> totalMonths;
cout << "What day of the week does the starting month fall on?\n";
cout <> startDay;
PrintSelectedMonths(year, month, startDay, totalMonths);
cout <> year;
}
return 0;
}
//———————————————————————–
// This function uses the integer month to print out that months name.
// It also prints out the one letter abbreviations for Sunday
// through Saturday and the underscores under them.
// Parameters: (in)
//———————————————————————–
void PrintMonthHeader(int month)
{
cout << "\n" << " " << MonthString(month) << '\n';
cout << " S M T W T F S\n";
cout < 0)
{
if (day == DAYS_IN_WEEK)
daySpaces = 0;
else
{
cout << " ";
daySpaces–;
}
}
while (daysInMonth <= lastday)
{
if (day % DAYS_IN_WEEK == 0 && daysInMonth != 1)
{
cout << "\n";
day = 0;
}
cout << setw(DAY_WIDTH) << daysInMonth;
daysInMonth++;
day++;
}
cout << endl;
return;
}
//———————————————————————–
// This function prints out the calendar for the given number
// of months (total_months), the given year, using the
// start_month and starting day (day). The function repeatedly
// calls PrintMonthHeader and PrintMonthBody.
// Parameters: (in, in, in, in)
//———————————————————————–
void PrintSelectedMonths(int year, int start_month,
int day, int total_months)
{
int monthCount = 0;
cout << "\n\n" << " " << year << "\n" ;
while(monthCount < total_months)
{
PrintMonthHeader(start_month);
PrintMonthBody(year, start_month, day);
if (start_month % 12 == 0 && total_months != 12)
{
year++;
cout << "\n\n\n" << " " << year << "\n" ;
monthCount = 1;
start_month = 0;
}
monthCount++;
start_month++;
}
return;
}