#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#include <conio.h>
#include <string.h>
#define ESC 0x1B
#define ENTER 0x0D
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//打印指定年月的日历的函数
void Print(int year, int month) {
int i, Weekday, ed=0, BASE=6, flag=0,Month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//计算Weekday
if ( year>1582 || (year==1582&&month>10 )) flag=1;
Month[0] = flag ? 2: 0;
if ( year%4 == 0 ) Month[2] = 29;
if(flag) if( year%100==0 && year%400!=0) Month[2] = 28;
for(i=0; i<month; i++){
ed += Month[i];
}
switch(flag){
case 0:{
Weekday = (BASE + (year-1) + (year-1)/4 + ed )%7;
break;
}
case 1: {
Weekday = (BASE + (year-1) + (year-1)/4 - (year-1)/100 + (year-1)/400 +ed )%7;
}
}
if(!Weekday) Weekday = 7;//如果计算得出Weekday值为0,则将其置为7
flag = 0;//flag重置,方便后续调用
//月历打印
//1.表头
printf("\nThe calendar of %02d/%04d(month/year).为防止作弊,此处打印你的姓名,余天润.\n",month,year);
printf("**********************************\n");
printf("MON TUE WEN THU FRI SAT SUN\n");
int j, n=0;
//2.空格
for(j=1; j<Weekday; j++){
printf(" ");
n++;
}
//3.日期
int Day[33];
if( year==1582 && month==10 ) flag = 1;
for(j=1; j<Month[month]+1; j++) Day[j] = j;
if(flag) {
for(j=5; j<15; j++){
Day[j] = 0;
}
}
for(j=1; j<Month[month]+1; j++)
{
if(!Day[j]) continue;
if(n!=0 && n%7 == 0) printf("\n");
printf("%-5d",Day[j]);
n++;
}
//4.表尾
printf("\n**********************************\n"); //一次打印结束,提示用户是否继续打印
printf("Press [N/n] for the next month;\n");
printf("Press [P/p] for the previous month;\n");
printf("Press [Esc] or other characters for exit.\n");
}
int main(int argc, char *argv[]) {
//改变控制台名称
const char * title = "月 历 打 印";
SetConsoleTitle(title);
char c, ch, nptr[10];
int i=0,year,month;
int flag=1;
do{
i=0;
flag=0;
printf("Pls input the year;\nPress [Enter] for now;\nPress [Esc] for exit.\n-->");
//第一步录入,首先判断是否是ESC或者ENTER,如果不是就存进数组nptr
c=getch();
if(c!=ESC&&c!=ENTER) {
printf("%c",c); //回显数字
if(!(c>='0'&&c<='9')) printf("\n"); } //格式美化,使提示重新输入的语句换行
while(1){
if(c==ENTER){ //如果输入“Enter”获取系统当前的时间
printf("\n");
time_t t;
struct tm *ym; //tm结构指针
t=time(NULL); //获取当前日期时间整数值
ym=localtime(&t); //转换为本地日期时间结构体
year=ym->tm_year+1900; //tm_year的基准为1900年
month=ym->tm_mon+1; //月份基准为0,转换为基准为1
}
else if (c==ESC) exit(1);
else {
memset(nptr,0,sizeof(nptr)) ;
while(c>='0'&&c<='9'){
nptr[i++]=c;
c=getche();
}
year=atoi(nptr);
printf("\n");//防止输入的年份被月份输入提示语句覆盖
while(1){
if(year>0) break;
printf("Error! Pls input the year again:");
c=getch();
if(c!=ESC&&c!=ENTER) {
printf("%c",c); //回显数字
if(!(c>='0'&&c<='9')) printf("\n"); //格式美化,使提示重新输入的语句换行
while(c>='0'&&c<='9'){
nptr[i++]=c;
c=getche();
}
year=atoi(nptr);
printf("\n");
}
}
printf("Pls input the month:");
scanf("%d",&month);
while(1){
if(month>=1&&month<=12) break;
printf("Error! Pls input the month again:");
scanf("%d",&month);
}
}
if(year>0) break;
}
printf("\n");
Print(year,month);
//第一次月历打印结束
//用户选择是否继续打印
ch = getch();
while(ch=='n'||ch=='N'||ch=='P'||ch=='p'){
if (ch=='N'||ch=='n'){
if(month==12) {
year++;
month=1;
}
else month++;}
else{
if(month==1){
year--;
if(year==0) exit(1);
month=12;
}
else month--;
}
Print(year,month);
ch=getch();
}
if(ch!='n'&&ch!='N'&&ch!='P'&&ch!='p') {//如果输入的不是n,N,p,P,清空控制台信息并且回到最开始由用户输入年月
system("cls");
flag=1;
}
}while(flag);
return 0;
}