1900.1.1为周一,最后一行会排不满,Res=sum%7+1统计最后几天要占最后一行的几格。Res不为7时说明最后一行没有排满,下个月开头要空出来,如果上一个月把最后一行占满了,这时Res=7,前面就不需要空。以前看别人写的有这方面出现错误。
变量Tmp为开头第一行有几个日期,日期数=Tmp且日期数-Tmp=7的倍数时要换行。
日期数组那里可以用一个二维数组解决
#include<stdio.h>
#include<stdlib.h>
int ping[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int run[12]={31,29,31,30,31,30,31,31,30,31,30,31};
int isleapyear(int year);
void print_star(); //初始表中的属性
int day_sum(int year,int month);
void print_calendar(int sum,int year,int month);
int main()
{
int year,month,sum;
printf("输入年(>=1900)和月,输入年为-1时结束\n");
printf("year="); scanf("%d",&year);
while(year!=-1)
{
printf("month="); scanf("%d",&month);
print_star();
sum=day_sum(year,month);
print_calendar(sum,year,month);
printf("********************************************************\n");
printf("year="); scanf("%d",&year);
}
return 0;
}
int isleapyear(int year)
{
if(((year%4==0)&&(year%100!=0))||(year%400==0)) return 1;
else return 0;
}
void print_star()
{
char week[7][10]={"日","一","二","三","四","五","六"};
printf("\t\t\t万年历\t\t\t\n");
printf("********************************************************\n");
for(int i=0;i<7;i++) printf("%s\t",week[i]);
printf("\n");
}
int day_sum(int year,int month)
{
int sum=0;
for(int i=1900;i<year;i++) //year为2020时加到2019
{
if(isleapyear(i)) sum+=366;
else sum+=365;
}
for(int j=0;j<month-1;j++) //month为3月的话加到2月
{
if(isleapyear(year)) sum+=run[j];
else sum+=ping[j];
}
return sum; //2020.3.1离1900.1.1有多少天
}
void print_calendar(int sum,int year,int month)
{
int Res,Tmp;
Res=sum%7+1; //1900.1.1是周一往后退一格,最后几天要占最后一行的几格
Tmp=7-Res; //新日历1日前面要空几格子
if(Res!=7)
{
for(int i=0;i<Res;i++) printf("\t");
}
if(isleapyear(year))
{
for(int j=1;j<=run[month-1];j++)
{
printf("%d\t",j);
if(Tmp==j||(j-Tmp)%7==0) printf("\n");
}
printf("\n");
}
else
{
for(int j=1;j<=ping[month-1];j++)
{
printf("%d\t",j);
if(Tmp==j||(j-Tmp)%7==0) printf("\n");
}
printf("\n");
}
}
效果: