题目:输出1900年之后任意一年的日历。原题出自《C语言的科学与艺术》P132
/* File name:calendar.c
Function:generate a calendar for a year
Time:2018.04.08.00:02
the source code from book《The art and science of C》,eric roberts
edited by qjx
*/
#include <stdio.h>
#define Sunday 0 //easy to qiumo(%)
#define Monday 1
#define Tuesday 2
#define Wednesday 3
#define Thursday 4
#define Friday 5
#define Saturday 6
void GiveInstruction(void); //tell the input rules
int GetYearFromUser(void);
void PrintCalendar(int year);
void PrintCalendarMonth(int month,int year); //the essence of this program
void IndentFirstLine(int weekday); //The spacebar of the first row of every month
char *MonthName(int month); //this function as string(char) function can transmit string to display
int MonthDays(int month,int year); //transmit the days of every month
int IsLeapYear(int year); //judge the input number is leapyear or not
main()
{
int Year;
GiveInstruction();
Year=GetYearFromUser();
PrintCalendar(Year);
}
void GiveInstruction(void) //tell the user how to do
{
printf("This program displays a calendar for a full\n");
printf("year. The year must not be before 1900.\n");
}
int GetYearFromUser(void)
{
int year;
while(1){
printf("Which year?");
scanf("%d",&year);
if(year>1900) return (year); //while the input is right,function will return
printf("The year must be at least 1900.\n"); //otherwise,waring and input again
}
}
void PrintCalendar(int year)
{
int month;
for(month=1;month<=12;month++)
{
PrintCalendarMonth(month,year); //print the every month is the essence of program
printf("\n");
}
}
void PrintCalendarMonth(int month,int year)
{
int weekday,nDays,day;
printf(" %s %d\n",MonthName(month),year); //the head of the monthly calendar
printf(" Su Mo Tu We Th Fr Sa\n");
nDays=MonthDays(month,year); //get the days of month,which will call IsLeapYear function
weekday=FirstDayOfMonth(month,year); //know first day of every month is which one of weekday
IndentFirstLine(weekday); //print the spacebar before the first day
for(day=1;day<=nDays;day++)
{
printf(" %2d",day); //printf the day
if(weekday==Saturday) printf("\n");
//if saturday,line feed;if not,the final weekday will line feed
weekday=(weekday+1)%7; //calculate next day
}
if (weekday!=Sunday) printf("\n");
//if not sunday,line feed;if sunday,the former weekday is sturday,has already line feed
}
void IndentFirstLine(int weekday) //The spacebar of the first row of every month
{
int i;
for(i=0;i<weekday;i++)
{
printf(" ");
}
}
char *MonthName(int month) //transmit the string of months
{
switch(month)
{
case 1:return ("January");
case 2:return ("February");
case 3:return ("March");
case 4:return ("April");
case 5:return ("May");
case 6:return ("June");
case 7:return ("July");
case 8:return ("August");
case 9:return ("September");
case 10:return ("October");
case 11:return ("November");
case 12:return ("December");
default:return ("Illegal month");
}
}
//calculate the numbers of every month,notice need to call IsLeapYear function
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;
}
}
int FirstDayOfMonth(month,year) //know first day of every month is which one of weekday
{
int weekday,i;
weekday=Monday;
for(i=1900;i<year;i++) //first according to the year
{
weekday=(weekday+365)%7; // % can get the weekday
if(IsLeapYear(i)) weekday=(weekday+1)%7;
}
for(i=1;i<month;i++) //second according to the month
{
weekday=(weekday+MonthDays(i,year))%7;
}
return weekday;
}
int IsLeapYear(int year) //judge the input number is leapyear or not
{
return ((year%400==0)||((year%4==0)&&(year%100!=0)));
}