由于原题所给代码存在一定bug,故本人采用另一种方法实现。
程序运行效果如图,在运行时输入合法的年月,程序将会显示对应月份的日历。
程序源码如下:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> void mkCalendar(int week, int day); //输出日历的函数 int calWeek(int year, int month,int day); //用于计算某天星期几的函数 int calDay(int year, int month); //用于计算某年某月天数的函数 int main(int a, char **date) { // int year=0,month=0,writeMonth=0; if (a == 1) { printf("Error!"); exit(0); //当没有输入年月时报错 } for (int i = 0; date[1][i]; i++) { if (date[1][i] == '-' || date[1][i] == '.' || date[1][i]== '/') { //新手注意判断是否相等时使用==运算符 writeMonth = 1; continue; } if (!writeMonth) { year = year * 10 + (date[1][i] - '0'); } if (writeMonth) { month = month * 10 + (date[1][i] - '0'); } } if (year < 1583 || month>12 || month < 1) { printf("Unsupported Date"); //处于简便考虑,没有对1582年10月及以前的日期采用另一公式,故不允许输入1583年以前的日期 exit(0); } mkCalendar(calWeek(year,month,1),calDay(year,month)); return 0; } void mkCalendar(int weeknum, int day) { int changeline = 0; printf("***************************\n"); printf("SUN MON TUE WED THU FRI SAT\n"); for (int i = 0; i < weeknum; i++) { printf(" "); changeline++; } for (int i = 1; i <= day; i++) { printf("%3d ", i); changeline++; if (changeline % 7 == 0&&i!= day) printf("\n"); } printf("\n***************************\n"); } int calWeek(int year, int month,int day) { int c, y, m, d=day,w; if (month == 1||month==2) { year -= 1; m = month + 12; } else m = month; c = year / 100; y = year % 100; w = ((c/4)-2*c+y+(y/4)+(13*(m+1)/5)+d-1) % 7; if (w < 0) w += 7; return w; } int calDay(int year, int month) { switch (month) { case 1:case 5:case 7:case 8:case 10:case 12: return 31; break; case 3:case 4: case 6: case 9: case 11: return 30; break; case 2: if(year%400==0||(year%4==0&&year%100!=0)) return 29; else return 28; break; } }本程序遵循IPO编程模式,从控制台读取日期,进行计算,并输出日历。
输入部分
int main(int a, char **date) { int year=0,month=0,writeMonth=0; if (a == 1) { printf("Error!"); exit(0); } for (int i = 0; date[1][i]; i++) { if (date[1][i] == '-' || date[1][i] == '.' || date[1][i]== '/') { writeMonth = 1; continue; } if (!writeMonth) { year = year * 10 + (date[1][i] - '0'); } if (writeMonth) { month = month * 10 + (date[1][i] - '0'); } }
处理部分
int calWeek(int year, int month,int day) { int c, y, m, d=day,w; if (month == 1||month==2) { year -= 1; m = month + 12; } else m = month; c = year / 100; y = year % 100; w = ((c/4)-2*c+y+(y/4)+(13*(m+1)/5)+d-1) % 7; if (w < 0) w += 7; return w; } int calDay(int year, int month) { switch (month) { case 1:case 5:case 7:case 8:case 10:case 12: return 31; break; case 3:case 4: case 6: case 9: case 11: return 30; break; case 2: if(year%400==0||(year%4==0&&year%100!=0)) return 29; else return 28; break; }
输出部分
void mkCalendar(int weeknum, int day) { int changeline = 0; printf("***************************\n"); printf("SUN MON TUE WED THU FRI SAT\n"); for (int i = 0; i < weeknum; i++) { printf(" "); changeline++; } for (int i = 1; i <= day; i++) { printf("%3d ", i); changeline++; if (changeline % 7 == 0&&i!= day) printf("\n"); } printf("\n***************************\n"); }