题目

  1. 编写程序,输入一个年份,打印该年份的日历,输出结果示例如题图所示。
    图片说明

思路

本题是对昨日的题的升级,原来是一次打印一个月,现在是横向一次打印两个月。首先要深刻理解打印规律是外层循环控制打印多少行、内层循环控制每一列打印什么。

代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

//返回输入日期距离年初的天数
int day_count(int y,int m,int d)
{
    int i,days=0;
    int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(i=0;i<m;i++)
    {
        days+=a[i];
    }
    days+=d;
    if(m>2 && (y%4==0 && y%100!=0 || y%400==0))
    {
        days++;
    }
    return days;
}


//输入日期,返回当月的1日是周几,1~7对应周一至周日
int weekdays(int y1,int m1)
{
    int d1=1,y2=2018,m2=2,d2=18,a,b,c=0,i,days,flag;
    a=day_count(y1,m1,d1);
    b=day_count(y2,m2,d2);
    if(y1<y2)
    {
        for(i=y1;i<y2;i++)
        {
            if(i%4==0 && i%100!=0 || i%400==0)
            {
                c++;
            }

        }
        days=b-a+(y2-y1)*365+c;
    }else{
        for(i=y2;i<y1;i++)
        {
            if(i%4==0 && i%100!=0 || i%400==0)
            {
                c++;
            }

        }
        days=a-b+(y1-y2)*365+c;
    }

    if((y1<y2) || (y1==y2 && m1<m2) ||(y1==y2 && m1==m2 && d1<d2))
    {
        flag=(7-days%7)%7;
    }else{
        flag=days%7;
    }
    if(flag==0)
    {
        flag=7;
    }
    return flag;
}


//输入year和month打印横向两月日历
void month_print(int y,int m)
{
    int h,i=1,j=1,k1,k2,flag=0,flag1=1;//flag用于记录是否为闰年
    //i,j分别记录横向相邻两月的日期,h为用于计数的变量
    //flag用于处理闰年,flag1用于让右侧1日前打印空格的语句只运行一次
    int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    printf("| %d  MON TUS WED THU FRI SAT SUN %3d  MON TUS WED THU FRI SAT SUN |\n",m,m+6);
    k1=weekdays(y,m);k2=weekdays(y,m+6);//k1,k2用于记录月份的第一天是周几
    if(m==2)
    {
        flag=(y%4==0 && y%100!=0 || y%400==0);
    }//处理闰年
    printf("|  ");
    //打印左侧月份1日前面可能存在的空格
    for(h=k1-1;h>0;h--)
    {
        printf("    ");
    }
    while(i<a[m] || j<=a[m+6])//打印主体开始
    {
        if(i!=1)
        {
            printf("|  ");
        }
        for(;;i++,k1++)
        {
            if(i<=a[m]+flag)
            {
                printf("%4d",i);
            }else{
                printf("    ");
            }
            if(k1%7==0)
            {
                k1++;i++;
                break;
            }
        }//左侧月份打印完一行
        printf("    ");//打印间隔
        if(flag1)
        {
            //打印右侧月份1日前可能存在的空格
            for(h=k2-1;h>0;h--)
            {
                printf("    ");
            }
            flag1=0;
        }
        for(;;j++,k2++)
        {
            if(j<=a[m+6])
            {
                printf("%4d",j);
            }else{
                printf("    ");
            }
            if(k2%7==0)
            {
                k2++;j++;
                printf("   |\n");
                break;
            }
        }//右侧月份打完一行
    }
}

int main()
{
    int year,mon;
    printf("please input the year whose calendar you want to know:");
    while(fflush(stdin),scanf("%d",&year)!=EOF)
    {
        mon=1;
        printf("|--------------------The Calendar of Year %d--------------------|\n",year);
        while(mon<=6)
        {
            month_print(year,mon);
            mon++;
        }
        printf("|-----------------------------------------------------------------|\n");
        printf("please input the year whose calendar you want to know:");
    }
    system("pause");
}

运行结果
图片说明
图片说明