打印日历

来源:互联网 发布:人工智能分析报告 编辑:程序博客网 时间:2024/05/23 01:50

输入一个年份然后打印日历,从书中修正得到

下面程序因为没有用蔡勒公式,选择了历史上已知的星期几的某一天进行计算。

#include <stdio.h>/*表示一周中的日子,对它进行了编号;这样编号有好处。倘若你知道某天是星期几可以用(weekday(0~6) + k)% 7求出该天是星期几,其中k表示第几天;例如:(5 + 10) % 7表示今天是星期五,今天后第十天是星期一;还可以求出本周的下一天是星期几,可移动到那一天不会出现weekday++带来的困扰;weekday = (weekday + 1) % 7;*/#define Sunday      0#define Monday      1#define Tuesday     2#define Wednesday   3#define Thursday    4#define Friday      5#define Saturday    6/*函数声明*/void GiveInstrutions(void);                    //提示函数;int GetyearFromuser(void);                     //输入年份,打印日历;void PrintCalendar(int year);                  //一年的1~12个月;void PrintCalendarMonth(int month, int year);  //显示某个月的日历;void IndentFirstLine(int weekday);             //输出日历的第一行,使第一天出现在正确的位置;int Monthdays(int month, int year);            //计算某月的天数;int FirstDayofMonth(int month, int year);      //计算某月的第一天是星期几;char *MonthName(int month);                    //打印出该月的名字;bool IsLeapyear(int year);                     //判断是不是闰年;int main(){        int year;        GiveInstrutions();        year = GetyearFromuser();        PrintCalendar(year);        return 0;}/*提示说明函数*/void GiveInstrutions(void){        printf("This program displays a calendar for a full\n");        printf("year.  The year must not be for 1900.\n");}/*输入年份*/int GetyearFromuser(void){        int year;        while(true)        {                printf("Which year?\n");                scanf("%d", &year);                if (year >= 1900) return (year);             //因为后面是以已知1900年1月1日是星期一作为计算的起点的;                printf("The year must be at least 1900.\n");        }}/*打印函数*/void PrintCalendar(int year){        int month;        printf("\n");        for (month=1; month<=12; month++)       //该年的1~12月;        {                PrintCalendarMonth(month, year);//调用打印月的函数;要知道该月有多少天,第一天是星期几;                printf("\n");                   //每个月之间要换行;        }}/*打印月的函数*/void PrintCalendarMonth(int month, int year){        int weekday, nDays, day;        printf("   %s %d\n", MonthName(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");       //即使这个星期不是在星期日结束,最后一行也有换行符;换成星期六也行;}/*确保第一天出现在正确的位置*/void IndentFirstLine(int weekday){        int i;        for (i=0; i<weekday; i++)                printf("   ");          //在前面打印空格;}/*计算该月的天数*/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(int month, int year){        int weekday, i;        weekday = Monday;            //因为1900年1月1日是星期一;        for (i=1900; i<year; i++)        {                weekday = (weekday + 365) % 7;                if (IsLeapyear(i))                        weekday = (weekday + 1) % 7;        }        /*此处计算出的是当年1月1日是星期几; 因为weekday = (weekday + k)% 7 计算的是从那天后的第k天,所以天数刚好多一*/        //printf("%d\n", weekday);        for (i=1; i<month; i++)        {                int sum = 0;                sum += Monthdays(i, year);                weekday = (weekday + sum) % 7;     //某月1号,所以要加上该年前几个月的天数;这里最重要;        }        return (weekday);}/*这里采用了一个简单的方法,取历史上的已知星期几的某一天;从那天开始算按闰年与否每年加365/366天;对于要算当年的要处理的月份之前的月,加上这月的天数;运用weekday = (weekday + k) % 7。*//*该月份的名字*/char *MonthName(int month){        switch(month)        {                case  1: return ("January");                case  2: return ("Fberuary");                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");        }}/*判断闰年与否*/bool IsLeapyear(int year){        return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));}/*仅供参考,已经测试,修正于C语言的编程与艺术的译本*/


0 0