//========================================================================= #define PROGRAMMER "SOLUTIONS, NoFrills" #define PROG_CODE "soln" #define COURSE "ECE-1021" #define YEAR (2003) #define TERM "Fall" #define SECTION (0) #define ASSIGNMENT "HW #2B" #define REVISION (0) #define TITLE "Printing a Calendar" #define SUBTITLE "Programming Exercise #4.6" #define EMAIL "wbahn@eas.uccs.edu" #define FILENAME "02b0soln.c" //========================================================================= // PROBLEM: // // Modify an existing program (Section 4.6) to print a calendar in a two // column format to a file and only requiring a year from the user. // // The steps to be followed to perform the modification are as follows: // // TASK #1: Implement the program as it presently exists in Sec 4.6. // The code is available on the course website in the // text book section. // TASK #2: Modify it to require only a year from the yser. // Using the formula given in the problem, compute the // day_code for Jan 1st and whether it is a leap year. // TASK #3: Modify it to print a second image shifted right. // This should be a simple matter of dublicating some printf() // statements. // TASK #4: Modify it to use a constant number of lines per month. // Just need to print a line of blank dates if necessary. // TASK #5: Modify it to prints only six months in a column. // Trivial (should be, anyway). // TASK #6: Identify which variables must be split between columns. // Probably daycode, month, and day - perhaps others. // TASK #7: Modify it to print the complete calendar. // Should just be a matter of using the new variables. // TASK #8: Modify it to print to a file instead of the screen. // Open and check the file and convert all of the printf() // statements to fprintf() statements using a search and // replace - or perhaps a macro. // TASK #9: OPTIONAL - pretty up the printout. //== RECORD OF MODIFICATIONS ============================================== // TASK #1: Implement the program as it presently exists in Sec 4.6. // // From the website, got the zip file containing the source code for all // of the problems in the text and copied the body into the Source Code // template. Inserted the PrintHeader() call at the proper place. Cleaned // up the formatting to being it into compliance with the course standards. // // Ran program and it works as expected. // // Time to perform Task #1: 6 minutes. // TASK #2: Modify it to require only a year from the yser. // // Replace the code for the user input with the code to compute these // items from the year alone. // // Time to perform Task #2: 7 minutes. // TASK #3: Modify it to print a second image shifted right. // // The goal is just to print the same contents shifted to the right so // that it is lined up in a second column. This will be done in to steps. // First, spaces will be printed to flesh out the line to column 40. Then // the same content will be reprinted. // // Had to modify code so that the month was printed out one week at a time // and that the month always contained exactly six printed weeks. // // Time to perform Task #3: 37 minutes. // TASK #4: Modify it to use a constant number of lines per month. // // This was done as part of Task #3 // // Time to perform Task #4: 0 minutes. // TASK #5: Modify it to prints only six months in a column. // TASK #6: Identify which variables must be split between columns. // TASK #7: Modify it to print the complete calendar. // // While performing Task #3, the details of how to do these three // tasks because apparent. The switch statement will respond to the // first six months but will set up the variable for both that month // and the month (siz months later) that will be printed in the right // column. A second set of variables is needed for the right hand // column consisting of R_day_code, R_day, R_days_in_month. // // Time to perform Tasks #5-#7: 15 minutes. // TASK #8: Modify it to print to a file instead of the screen. // // This is just a matter of opening the file calendar.dat, verifying // that it opened, and changing the printf() statements to fprintf() // statements. // // Time to perform Tasks #8: 5 minutes. //== INCLUDE FILES ======================================================== #include // printf() //== MACROS =============================================================== //== FUNCTION PROTOTYPES ================================================== void PrintHeader(void); //== MAIN FUNCTION ======================================================== int main(void) { int day_code, // day_code = 0 means the month starts on Sun days_in_month, // number of days in month currently being printed */ leap_year, // 1 means leap year; 0 means no leap year day, // counter for day of month month; // month = 1 is Jan, month = 2 is Feb, etc. int year; // Year of the calandar. int week; // The week of the month 0 to 5 int i; // dummy counter; int R_day, R_day_code, R_days_in_month; // Variable set for RH column. FILE *fp; PrintHeader(); printf("\n"); // Print a blank line printf( "Enter the year for which you want the calendar printed: "); scanf( "%i", &year); // Using integer division intentionally: day_code = ( year + (year-1)/4 - (year-1)/100 + (year-1)/400 )%7; if(year%4) // TRUE if x is NOT divisible by 4 leap_year = 0; else if(year%100) // TRUE if x is divisible by 4 but NOT 100 leap_year = 1; else if(year%400) // TRUE if x is divisible by 100 but NOT 400 leap_year = 0; else leap_year = 1; if(leap_year) R_day_code = day_code; else R_day_code = (day_code + 6)%7; if(NULL == (fp = fopen("calendar.dat", "wt"))) { printf("Error opening calendar.dat for writing - aborting!\n"); return(1); } fprintf(fp, "\n"); fprintf(fp, " Calendar for Year %4i\n", year); for( month = 1; month <= 6; month++ ) { switch ( month ) { // print name and set days_in_month case 1: fprintf(fp, "\n January " ); days_in_month = 31; fprintf(fp, " July" ); R_days_in_month = 31; break; case 2: fprintf(fp, "\n February " ); days_in_month = leap_year ? 29 : 28; fprintf(fp, " August" ); R_days_in_month = 31; break; case 3: fprintf(fp, "\n March " ); days_in_month = 31; fprintf(fp, " September" ); R_days_in_month = 30; break; case 4: fprintf(fp, "\n April " ); days_in_month = 30; fprintf(fp, " October" ); R_days_in_month = 31; break; case 5: fprintf(fp, "\n May " ); days_in_month = 31; fprintf(fp, " November" ); R_days_in_month = 30; break; case 6: fprintf(fp, "\n June " ); days_in_month = 30; fprintf(fp, " December" ); R_days_in_month = 31; break; } fprintf(fp, "\n Sun Mon Tue Wed Thu Fri Sat " ); fprintf(fp, " Sun Mon Tue Wed Thu Fri Sat" ); fprintf(fp, "\n"); // We will print six full weeks of numbers. If the "number" for // a given location is not within the current month, we will // print two blank spaces in the number's place. // // We can assign "dates" to the days of the first week prior // to the actual start of the month by just numbering them // backward. // // If the week starts on Sunday (day_code = 0) then Sunday is 1 // If the week starts on Monday, (day_code = 1) then Sunday is 0 // If the week starts on Saturday, (day_code = 6) then Sunday is -5 // // So the first Sunday's "date" is 1 - day_code // The dates for the succeeding Sundays can be obtained by adding // multiples of 7. for(week = 0; week <6; week++) { // Left Hand Month fprintf(fp, " "); // Left Margin day = (1 - day_code) + 7*week; for(i = 0; i < 7; i++, day++) { if( (1 > day) || (days_in_month < day) ) fprintf(fp, " "); else fprintf(fp, " %2i ", day); } fprintf(fp, " "); // Finish the 40 spaces on left side. // Right Hand Month fprintf(fp, " "); // Left Margin R_day = (1 - R_day_code) + 7*week; for(i = 0; i < 7; i++, R_day++) { if( (1 > R_day) || (R_days_in_month < R_day) ) fprintf(fp, " "); else fprintf(fp, " %2i ", R_day); } fprintf(fp, "\n"); // Go on to next week; } // set day_code for next month to begin day_code = ( day_code + days_in_month ) % 7; R_day_code = ( R_day_code + R_days_in_month ) % 7; } fclose(fp); return(0); } //== SUPPORT FUNCTIONS ==================================================== void PrintHeader(void) { printf("========================================" "=======================================\n"); printf("Course....... %s-%i (%s %i)\n", COURSE, SECTION, TERM, YEAR); printf("Programmer... %s (%s)\n", PROGRAMMER, PROG_CODE); printf("Assignment... %s (Rev %i) (Source Code in %s)\n", ASSIGNMENT, REVISION, FILENAME); printf("Description.. %s\n", TITLE); printf(" %s\n", SUBTITLE); printf("========================================" "=======================================\n"); return; }