/* Program to print a picture of a calendar month. Input must be the number of days in a month, and the day in the week of the first day of the month. There must be at least 8 days in a month, and the day in the week must be from 0 to 6 (0=Sunday, 6=Saturday). Output is a 'calendar' style picture of the month. */ #include /***** Global variables to specify calendar required *****/ int last_day; /* Number of days in the month */ int start_weekday; /* Week day of the first of the month */ /********************* Functions **********************/ void obtain_user_input (void); void check_input_legality (void); void print_calendar_month (void); main () { /* Input the number of days and the starting day of the week. */ obtain_user_input(); /* Make sure input is legal, ask user to re-enter until it is. */ check_input_legality(); /* Print the picture of the month. */ print_calendar_month(); } /****************** obtain_user_input ****************** Gets user's values for last_day and start_weekday. */ void obtain_user_input (void) { printf("How many days are in the month? "); scanf("%d", &last_day); printf("Which week day is the first of the month?\n"); printf("(0=sun, 1=mon, 2=tue. 3=wed, 4=thu, 5=fri, 6=sat)\n"); scanf("%d", &start_weekday); } /**************** check_input_legality ****************** Makes sure user has entered last_day >= 8 and start_weekday between 0 and 6. Note: last_day is not restricted to 28..31 because some calendars used in the world have months of other lengths. */ void check_input_legality (void) { void obtain_user_input (void); while ( last_day < 8 || start_weekday < 0 || start_weekday > 6 ) { if (last_day < 8) { printf("The month must have eight or more days.\n"); } if (start_weekday < 0 || start_weekday > 6) { printf("The starting week day must be between 0 & 6\n"); } printf("Please re-enter both values.\n"); obtain_user_input(); } } /************ print_calendar_month ****************************** Prints the calendar picture. On entry: last_day is the number of days in the month, and must be greater than seven. start_weekday is the day-of-the-week of the first of the month, and must indicate a valid week day (0 to 6). */ void print_calendar_month (void) { void print_top_asterisks (int start_weekday); void print_calendar_row (int sun_date, int last_day); void print_full_line_asterisks (void); void print_bottom_asterisks (int sun_date, int last_day); int sun_date; /* date of Sunday in the week to be printed */ /* prepare to print the first week. (The date of Sunday of week 1 is on or before the first of the month. Since start_weekday is the 1st of the month, Sunday (0) must be the (1-start_weekday)st. If this is less than 1, Sunday is not in the month, so some blank days will be printed.) */ sun_date = 1 - start_weekday; /* print the top line of asterisks. */ print_top_asterisks(start_weekday); /* while we have not printed the second-last row, print another. (We have reached the last week if sun_date is within the final seven days of the month.) */ while (sun_date < last_day - 6) { /* Here sun_date is Sunday's date in the week to be printed. */ print_calendar_row(sun_date, last_day); sun_date += 7; /* prepare for the next week */ print_full_line_asterisks(); } /* print the last calendar row */ /* Here sun_date is Sunday's date in the final week. */ print_calendar_row(sun_date, last_day); print_bottom_asterisks(sun_date, last_day); } /******************************************************************/ /* Functions for outputting the calendar */ /* The following #defines allow us to change our minds about the appearance of the calendar with minimal effort. */ /* Full width of a square (cannot be less than 4): */ #define SQUARE_WIDTH 9 /* Height of area BETWEEN rows of asterisks (must be at least 1): */ #define SQUARE_HEIGHT 3 void putout (int number, char whichchar); /************************ print_calendar_row: ********************** On entry: sun_date is the date of Sunday in the week to be printed. If this is the first week, sun_date can be less than one. If so, sun_date should be 1 - start_weekday so that the first falls on start_weekday. last_date must be correct. Prints a calendar row (i.e. minus top & bottom asterisks) for the indicated week. If a day has a date less than 1 or greater than last_day, its square in the calendar is blanked (as the day is not within the month). */ void print_calendar_row (int sun_date, int last_day) { int line, day; for (line=1; line<=SQUARE_HEIGHT; line++) { /*Print one text line */ for (day=sun_date; daylast_day) { /* day is beyond end of month - print nothing */ /* NOTHING TO DO */ } else { /* day is within month - print square pieces */ putchar('*'); /* print left asterisk */ if (line==1) { /* First line needs a number */ printf("%3d", day); putout(SQUARE_WIDTH - 4, ' '); /* rest of square */ } else { /* other lines are an empty box */ putout(SQUARE_WIDTH - 1, ' '); } } } printf("*\n"); /* Terminate final box and add a newline */ } } /********************* putout ************************* A short utility function to output repeated characters. On entry: number is how many characters to print, whichchar is the character to be printed. Prints whichchar, number times. */ void putout (int number, char whichchar) { int i; for (i=0; i