每行按照YYYY-MM格式输入年月,需要你按下图格式打印该月月历。处理到文件结束。(YYYY >= 2000,已知2000年1月1日是周六)
(2022年12月30日)感谢@m0_73173543 同学指出问题,以下是更正
更正的代码:
# include <stdio.h>
int M[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int sum(int x)
{
int s = 0;
for (int i = 0; i < x; i++) s += M[i];
return s;
}
int main(void)
{
int y, m;
while (scanf_s("%d-%d", &y, &m) != EOF)
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
M[1] = 29;
else
M[1] = 28;
// 改的下一行
int days = 365 * (y - 2000) + (y-1 - 2000) / 4 - (y-1 - 2000) / 100 + (y-1 - 2000) / 400 + sum(m - 1);
if (y != 2000) days++;
int week = (days + 6)%7;
printf("\t\t\t%d-%s%d\n", y, m >= 10 ? "" : "0", m);
printf("Sun.\tMon.\tTue.\tWen.\tTur.\tFri.\tSat.\n");
int printEnter = week;
while (week--) printf("\t");
for (int i = 1; i <= M[m - 1]; i++)
{
printEnter++;
printf("%d%s", i, printEnter % 7 == 0 ? "\n" : "\t");
}
if (printEnter % 7 != 0) printf("\n");
}
return 0;
}
详细说明:
1.之前的错误原因:在计算从2000至YY-1之间闰年个数的时候错了
由于是计算到YY-1,不是YY,所以把原代码中365 * (y - 2000) + (y - 2000) / 4 - (y - 2000) / 100 + (y - 2000) / 400后三个y改成y-1即可
代码:
// 计算该月第一天是周几 已知:2000-1-1 sat
int days = 365 * (y - 2000) + (y-1 - 2000) / 4 - (y-1 - 2000) / 100 + (y-1 - 2000) / 400 + sum(m - 1);
if (y != 2000) days++;
int week = (days + 6)%7; //周日就是0,正好0个tab
——————————————原分析以及错误的地方的更改——————————————
分析:
1.首先要知道这个月第一天是周几。先计算2000-1-1至这个月的上一个月的总天数days,然后加6 再mod 7就可以得到是周几(0是周日)
2.days分成两部分:一是2000到YYYY-1整年天数,二是YYYY这一年的前MM-1个月天数
3.整年天数 = 365 * (y - 2000) + (y - 2000) / 4 - (y - 2000) / 100 + (y - 2000) / 400(“四年一闰百年不闰四百年又一闰”顺着口诀就写下来啦)
!!!※ 更改为( y -1 - 2000) / 4 - (y -1 - 2000) / 100 + (y -1 - 2000) / 400
注意第一个365 * (y - 2000)不改
4.整月天数用函数sum计算,而一年各个月天数已经提前存到数组M里
5.但是闰年的2月有29天,所以一上来还要先判断YYYY是闰年吗,是就把M[1]改成29(因为是多组输入,所以如果是YYYY是平年的话2月还要改回28~不然只要出现一个YYYY是闰年,之后的多组输入2月都是29天了)
6.计算完成,接下来调格式部分略。
7.但第3步有问题——
8.2000年本身是个闰年,把它当成一个整年计算时少加了1,判断一下加上就行啦。
原代码如下:(有一行不对,新代码在开头)
# include <stdio.h>
int M[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int sum(int x)
{
int s = 0;
for (int i = 0; i < x; i++) s += M[i];
return s;
}
int main(void)
{
int y, m;
while (scanf_s("%d-%d", &y, &m) != EOF)
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
M[1] = 29;
else
M[1] = 28;
// 计算该月第一天是周几 已知:2000-1-1 sat
int days = 365 * (y - 2000) + (y - 2000) / 4 - (y - 2000) / 100 + (y - 2000) / 400 + sum(m - 1);
if (y != 2000) days++;
int week = (days + 6) % 7; //周日就是0,正好0个tab
printf("\t\t\t%d-%s%d\n", y, m >= 10 ? "" : "0", m);
printf("Sun.\tMon.\tTue.\tWen.\tTur.\tFri.\tSat.\n");
int printEnter = week;
while (week--) printf("\t");
for (int i = 1; i <= M[m - 1]; i++)
{
printEnter++;
printf("%d%s", i, printEnter % 7 == 0?"\n":"\t");
}
if (printEnter % 7 != 0) printf("\n");
}
return 0;
}