#include "stdio.h" #include "stdlib.h" //判断闰年 int isLeapYear(int year) { if(year%400==0||(year%100!=0&&year%4==0)) { return 1; } return 0; } // 计算某年某月的天数 int daysInMonth(int year, int month) { int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && isLeapYear(year)) { return 29; } return days[month - 1]; } // 计算公元1年1月1日到给定日期的总天数 int totalDays(int year, int month, int day) { int total = 0; for (int i = 1; i < year; i++) { if ((i % 4 == 0 && i % 100!= 0) || i % 400 == 0) { total += 366; } else { total += 365; } } for (int i = 1; i < month; i++) { if (year == 1582 && i == 10) { // 如果是1582年且计算到10月,减去10天 if (day >= 15) { day -= 10; } } total += daysInMonth(year, i); } total += day; return total; } // 判断输入是否为合法的数字 int isNumber(char *input) { for (int i = 0; input[i]!= '\0'; i++) { if (input[i] < '0' || input[i] > '9') { return 0; } } return 1; } // 判断日期是否合法 int isValidDate(int year, int month, int day) { if (year <= 0) { return 0; } if (month < 1 || month > 12) { return 0; } if (day < 1 || day > daysInMonth(year, month)) { return 0; } return 1; } //1852 int a(int year,int month,int day) { if(year==1582) { return 0; } if(month==10) { return 0; } if(day>4&&day<15) { return 0; } return 1; } // 输出一个月的日历 void printMonth(int year, int month) { printf(" %d年%d月\n", year, month); printf("日 一 二 三 四 五 六\n"); int startDay = (totalDays(year, month, 1) % 7); for (int i = 0; i < startDay; i++) { printf(" "); } int days = daysInMonth(year, month); for (int i = 1; i <= days; i++) { printf("%2d ", i); if ((totalDays(year, month, i) % 7) == 6) { printf("\n"); } } if ((totalDays(year, month, days) % 7)!= 6) { printf("\n"); } } // 获取指定日期是周几 int isWeek(int totalDay) { return (totalDay % 7); } // 计算某月某天的日期 int Count_Day(int day[]) { return (day[0] * 1000 + day[1] * 100 + day[2] * 10 + day[3]); } // 双列输出日历的核心函数 void printDoubleColumnCalendar(int year) { // 对2个月分为6个块进行打印 for (int block = 0; block < 6; ++block) { // 打印表头 printf("%2d月 %2d月 \n", block + 1, block + 7); printf("日 一 二 三 四 五 六 日 一 二 三 四 五 六\n"); int lineEnd_l = 1, lineEnd_r = 1; int day_l[] = {year, block + 1, 1}; int day_r[] = {year, block + 7, 1}; int totalDay_l = Count_Day(day_l); int totalDay_r = Count_Day(day_r); // 每个月有5行需要输出 for (int line = 0; line < 5; ++line) { // flag作标记位,每行有16个输出数字的位置,第9位和16位始终置0,其余位置不为0则输出数字 int flag[16] = {0}; // 标记第一行和其它行,用lineEnd_L和R作为整体的日期统计 if (line == 0) { int monthFirstday_l = isWeek(totalDay_l) + 1; int monthFirstday_r = isWeek(totalDay_r) + 1; for (int stringStation = monthFirstday_l; stringStation < 8; ++stringStation) { flag[stringStation] = lineEnd_l++; } for (int stringStation = monthFirstday_l + 8; stringStation < 16; ++stringStation) { flag[stringStation] = lineEnd_r++; } } else { for (int stringStation = 1; stringStation < 8; ++stringStation) { flag[stringStation] = lineEnd_l++; if (lineEnd_l > (daysInMonth(year, block + 1))) { break; } } for (int stringStation = 9; stringStation < 16; ++stringStation) { flag[stringStation] = lineEnd_r++; if (lineEnd_r > (daysInMonth(year, block + 7) + 1)) { break; } } } // 输出每行的日期 for (int i = 1; i < 16; ++i) { if (i == 9) { printf(" "); } if (flag[i] == 0) { printf(" "); } else { if (flag[i] < 10) { printf(" %d", flag[i]); } else { printf(" %d", flag[i]); } } } printf("\n"); } } } // 菜单选项1:判断闰年和星期几 void option1(void) { char yearStr[10], monthStr[10], dayStr[10]; int year, month, day; // 输入年份并验证 printf("请输入年份:"); scanf("%s", yearStr); if (!isNumber(yearStr)) { printf("输入错误,请输入数字!\n"); return; } year = atoi(yearStr); // 输入月份并验证 printf("请输入月份:"); scanf("%s", monthStr); if (!isNumber(monthStr)) { printf("请输入数字!\n"); return; } month = atoi(monthStr); // 输入日期并验证 printf("请输入日期:"); scanf("%s", dayStr); if (!isNumber(dayStr)) { printf("输入错误,请输入数字!\n"); return; } day = atoi(dayStr); // 验证日期整体合法性 if (!isValidDate(year, month, day)) { printf("日期不合法!\n"); return; } if(!a(year,month,day)) { printf("不存在此日期。\n"); return; } // 判断闰年并输出 if (isLeapYear(year)) { printf("%d年是闰年。\n", year); } else { printf("%d年不是闰年。\n", year); } // 计算并输出星期几 int total = totalDays(year, month, day); char *weekdays[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; printf("%d年%d月%d日是%s\n", year, month, day, weekdays[total % 7]); } // 菜单选项2:输出一年的日历(实现较好的双列输出) void option2(void) { char choiceStr[10]; int choice; // 选择输出方式并验证 printf("请选择输出方式(1: 单列输出,2: 双列输出): "); scanf("%s", choiceStr); if (!isNumber(choiceStr)) { printf("输入错误,请输入数字!\n"); return; } choice = atoi(choiceStr); if (choice!= 1 && choice!= 2) { printf("选择错误!\n"); return; } char yearStr[10]; int year; // 输入年份并验证 printf("请输入年份:"); scanf("%s", yearStr); if (!isNumber(yearStr)) { printf("输入错误,请输入数字!\n"); return; } year = atoi(yearStr); if (year <= 0) { printf("年份不合法!\n"); return; } //单列输出 if (choice == 1) { for (int month = 1; month <= 12; month++) { printMonth(year, month); } } else { printDoubleColumnCalendar(year); } } int main(void) { int choice; while(choice<=2) { // 显示菜单并获取用户选择 printf("1. 判断闰年和星期几\n"); printf("2. 输出一年的日历\n"); printf("请选择:"); scanf("%d", &choice); switch (choice) { case 1: option1(); break; case 2: option2(); break; default: printf("退出程序\n"); break; } } return 0; }