除非我误解了什么,否则您唯一担心的是如何在工作日标题下对齐第一部分的数字。由于每个月的第一天是第一天,你可以专注于weekDay(year,month,1)。
此外,由于日期都由 8 个字符(一个正常tab宽度)分隔,因此您可以简单地为每个工作日偏移量插入 8 个空格。因此,您基本上需要在第一天填充空格总数:
padding = weekDay(year,month,1) * 8;
这使您可以消除循环并简单地使用设置的字段宽度修饰符作为输出空格时padding的第一个参数,例如printf
int days, wd, padding; /* add padding variable */
...
// for (int d = 1; d <= 1 + weekDay(year,month,d) * 5; d++)
// {
// printf(" ");
// }
if ((padding = weekDay(year,month,1) * 8))
printf ("%*s", padding, " ");
或者在计算 之后padding,您可以简单地循环输出空格的次数,例如
padding = weekDay(year,month,1) * 8;
while (padding--)
putchar (' ');
无论哪种方式,结果都是一样的。
示例使用/输出
这似乎做了你正在尝试的事情,例如
2020 年 3 月
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
===================================================
2020 年 4 月:
$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
APR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
===================================================
2020 年 5 月:
$ ./bin/calendar
enter mm yyyy : 5 2020
===================================================
MAY/20
SUN MON TUE WED THU FRI SAT
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
===================================================
在开头和结尾添加占位符
如果您想"-- "为空日期添加占位符,那么要在开头添加占位符,您可以循环多次填充完整的字符串,例如
padding = weekDay(year,month,1);
while (padding--)
fputs ("-- ", stdout);
最后,重新计算从最后一天到最后的填充,例如
padding = 7 - weekDay(year,month,days) - 1;
while (padding--)
fputs ("-- ", stdout);
puts("\n===================================================");
示例使用/输出
使用占位符,您将拥有:
2020 年 2 月:
$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
FEB/20
SUN MON TUE WED THU FRI SAT
-- -- 01 02 03 04 05
06 07 08 09 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 -- -- -- --
===================================================
2020 年 3 月:
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 -- -- -- --
===================================================
2020 年 4 月:
$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
APR/20
SUN MON TUE WED THU FRI SAT
-- -- -- 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 -- --
===================================================
使用我的日历进行的验证似乎是正确的。我用来测试的完整代码是:
(更新:修复weekDay()计算)
#include <stdio.h>
#include <math.h>
const char weekday_str[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
const char month_str[13][4] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN","JUL",
"AGO", "SEP", "OCT", "NOV", "DEC"};
const int days_in_months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int weekDay (int yr, int mh, int d)
{
int y, c, m, w;
if (mh == 1 || mh == 2)
yr--;
y = yr % 100;
c = (yr - y) / 100;
if (mh == 1 || mh == 2)
m = mh + 10;
else if (mh <= 12 || mh >= 3)
m = mh - 2;
w = ((d + floor(2.6*m - 0.2) + y + floor(0.25*y) + floor(0.25*c) - 2*c ));
w = w % 7;
if(w < 0)
w += 7;
return w;
}
int isLeap (int year)
{
if (year%4 != 0)
return 0;
else if (year%100 != 0)
return 1;
else if (year%400 != 0)
return 0;
else
return 1;
}
void calendar (int year, int month)
{
int days, wd, padding;
puts ("===================================================");
printf (" %c%c%c/%d\n",
month_str[month][0],month_str[month][1],month_str[month][2],year);
puts ("\nSUN MON TUE WED THU FRI SAT");
if (month == 2) {
if (isLeap(year) == 1)
days = 29;
if (isLeap(year) == 0)
days = 28;
}
else
days = days_in_months[month];
padding = weekDay(year,month,1);
while (padding--)
fputs ("-- ", stdout);
for (int i = 0; i < days; i++) {
wd = weekDay(year,month, i + 1);
printf("%.2d", i + 1);
if ((wd+1) % 7 == 0)
printf("\n");
else
printf(" ");
}
padding = 7 - weekDay(year,month,days) - 1;
while (padding--)
fputs ("-- ", stdout);
puts("\n===================================================");
}
int main (void) {
int mm, yyyy;
fputs ("enter mm yyyy : ", stdout);
if (scanf ("%d %*c%d", &mm, &yyyy) != 2) {
fputs ("error: invalid format.\n", stderr);
return 1;
}
calendar (yyyy, mm);
}
无效weekDay()计算
1 月或 2 月日历的问题是 m = mh;您有:
if (mh == 1 || mh == 2)
m = mh + 10;
if (mh <= 12 || mh >= 3)
m = mh - 2;
你需要:
if (mh == 1 || mh == 2)
m = mh + 10;
else if (mh <= 12 || mh >= 3)
m = mh - 2;
原因:在您调整后Jan或再次检查时,Feb由于您刚刚添加,现在是正确的,因此您确实导致了错误的值。m = mh + 10;if (mh <= 12 || mh >= 3)+ 10m = mh - 2mh
示例使用/输出
2020 年 1 月
$ ./bin/calendar
enter mm yyyy : 1 2020
===================================================
JAN/20
SUN MON TUE WED THU FRI SAT
-- -- -- 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 --
===================================================
2020 年 2 月
$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
FEB/20
SUN MON TUE WED THU FRI SAT
-- -- -- -- -- -- 01
02 03 04 05 06 07 08
09 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
===================================================
2020 年 3 月
$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
MAR/20
SUN MON TUE WED THU FRI SAT
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 -- -- -- --
===================================================
如果您有任何问题,请告诉我。