/*
*File:PrintCalendar.c
*---------------------
*用户输入年份(1900年以后),自动打印出此年的日历
*/
#include<stdio.h>
#define Sunday 0
#define Monday 1
#define Tuesday 2
#define Wednesday 3
#define Thursday 4
#define Friday 5
#define Saturday 6
/*Function Prototypes*/
void GiveInstructions(void);
int GetYearFromUser(void);
void PrintCalendar(int year);
void PrintCalendarMonth(int month, int year);
void IndentFirstLine(int weekday);
int MonthDays(int month, int year);
int FirstDayOfMonth(int month, int year);
bool IsLeapYear(int year);
/*Main Program*/
main()
{
int year;
GiveInstructions();
year = GetYearFromUser();
PrintCalendar(year);
}
/* GiveInstruction(void)给出用户此程序的功能.*/
void GiveInstructions(void)
{
printf("This program displays a calendar for a full year.\n");
printf("The year must be after 1900.\n");
}
/* year = GetYearFromUser()让用户输入年份.*/
int GetYearFromUser()
{
int year;
while(1 > 0) {
printf("Which year?\n");
scanf("%d", &year);
if(year >= 1900) return(year);
printf("The year must be at least 1900.\n");
}
}
/* PrintCalendar(year) 调用PrintCalendarMonth(month, year)来输出一整年的日历*/
void PrintCalendar(int year)
{
int month;
for(month = 1; month <= 12; month++) {
PrintCalendarMonth(month, year);
printf("\n");
}
}
/* printCalendarMonth(month, year) 用来输出给定年的给定月的日历,weekday是取值在1~7的整型变量*/
void PrintCalendarMonth(int month, int year)
{
int weekday, nDays, day;
printf(" %s %d\n", month, year);
printf("Su Mo Tu We Th Fr Sa\n");
nDays = MonthDays(month, year);
weekday = FirstDayOfMonth(month, year);
IndentFirstLine(weekday);
for(day = 1; day <= nDays; day++) {
printf("%2d", day);
if(weekday = Saturday) printf("\n");
weekday = (weekday + 1) % 7;
}
if(weekday != Sunday) printf("\n");
}
/* IndentFirstLine(weekday) 使每个月的一号显示在正确的位置*/
void IndentFirstLine(int weekday)
{
int i;
for(i = 0; i < weekday; i++) {
printf(" ");
}
}
/* MonthDays(month, year) 求出给定年的某月的天数*/
int MonthDays(int month, int year)
{
switch(month) {
case 2:
if(IsLeapYear(year)) return(29);
return(28);
case 4: case 6: case 9: case 11:
return(30);
default:
return(31);
}
}
/* FirstDayOfMonth(month, year)求出此年此月的一号是星期几(根据1900年1月1
日是星期一来求)*/
int FirstDayOfMonth(int month, int year)
{
int weekday, i;
weekday = Monday;
for(i = 1900; i < year; i++) {
weekday = (weekday + 365) % 7;
if(IsLeapYear(i)) weekday = (weekday + 1) % 7;
}
for(i = 1; i < month; i++) {
weekday = (weekday + MonthDays(i, year)) % 7;
}
return(weekday);
}
/* IsLeapYear(year) 判断十分为闰年*/
bool IsLeapYear(int year)
{
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}