> 下月、< 上月、? 自定義年月、# 退出abc.txtint isLeap(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int monthDays(int month, int year) {
static int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
if (month == 2 && isLeap(year)) return 29;
return days[month-1];
}
累計從基準日期(如 1900-01-01 周一)到目標月首日的總天數,模 7 得星期。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h> // Windows專用,Linux請用 ncurses 或 termios
#include <string.h>
int isLeap(int y) { return (y%4==0&&y%100!=0)||(y%400==0); }
int monthDays(int m, int y) {
int d[12]={31,28,31,30,31,30,31,31,30,31,30,31};
return (m==2&&isLeap(y))?29:d[m-1];
}
void printCal(int y, int m) {
system("cls"); // Windows清屏,Linux用 system("clear")
printf("%d年%d月\n", y, m);
puts("Sun Mon Tue Wed Thu Fri Sat");
int days = monthDays(m, y);
// 計算1號星期 (0=Sun)
int total = 0;
for (int i = 1900; i < y; i++) total += isLeap(i) ? 366 : 365;
for (int i = 1; i < m; i++) total += monthDays(i, y);
int w = (total + 1) % 7; // 1900-01-01 是周一(1),調整為0基準
for (int i = 0; i < w; i++) printf(" ");
for (int d = 1; d <= days; d++) {
printf("%3d ", d);
if ((w + d) % 7 == 0) puts("");
}
puts("\n\n> Next < Prev ? Custom # Quit");
}
int main() {
int y, m;
printf("Year: "); scanf("%d", &y);
printf("Month: "); scanf("%d", &m);
getchar();
while (1) {
printCal(y, m);
switch (getch()) {
case '>': m++; if (m > 12) { m = 1; y++; } break;
case '<': m--; if (m < 1) { m = 12; y--; } break;
case '?': printf("Year: "); scanf("%d", &y);
printf("Month: "); scanf("%d", &m); getchar(); break;
case '#': return 0;
}
}
}
conio.h、getch()、system("cls") 僅限 Windows。#include <termios.h> #include <unistd.h> 實現無緩衝輸入system("clear") 清屏time.h 獲取系統時間)。scanf 後殘留換行符,需 getchar() 清理。