UIT2024_Calendar/stu2024/软件2401陈思宇(1).cpp
2024-12-07 16:23:34 +08:00

385 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include<bits/stdc++.h>
//需求:
//1.设计判断闰年函数
//2.设计查询某年某日日期星期几,
//3.日历的输出(单双列)
//4.菜单选择要有纠错功能 ,也就是说每个菜单要有一个函数可供返回 ,即每个最好要有一个单独的函数来满足
//5.1528年少了十天,据查证是因为罗马教皇决定在1582年10月4日后使用格利戈里历法英国是在1752年9月3日后才接受使用格利戈里历法
//1.闰年判断函数,思路:常见判断闰年条件
int isLeapyear(int year)
{
return(year%400==0)||(year%4==0&&year%100!=0);//如果是闰年,则为真
}
int monthsday(int year,int month)
{
int monthsday[]={31,28,31,30,31,30,31,31,30,31,30,31};
if (month==2&&isLeapyear(year))//如果是闰年,二月有二十九天
{
return 29;
}
return monthsday[month-1];
}
int getFirstDayOfYear(int year)//今年的第一天是周几
{
int d=(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400;
if (year>1582)
{
if (year==1583)
{
d-=10;
}
}
return d%7;
}
int getDaysInMonth(int year,int month)
{
int daysInMonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(month==2&&isLeapyear(year))
{
return 29;//闰年二月有29天
}
if (year == 1582 && month == 10) {
return 21; // 1582年十月只有21天
}
return daysInMonth[month-1];//返回对应月份的天数
}
//计算给定日期是星期几0表示星期日1-6表示周一到周六
int getDayOfWeek(int year, int month, int day)
{
int t[]={0,3,2,5,0,3,5,1,4,6,2,4};//调整不同月在不同年中的偏移
if (month<3)
{
year--;
}
return(year+year/4-year/100+year/400+t[month-1]+day)%7;
}
//2.查询哪年哪月是周几
int week(int year,int month,int day)//运用泰勒公式
{
if(month<3)
{
month+=12;
year--;
}
if(year<1583)
{
int h=(day+1+2*month+3*(month+1)/5+year+year/4+5)%7;
return h; //h表示某时间是星期几
}
else{
int h=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7;//蔡勒公式w=(d + 1+ 2*m+3*(m+1)/5+y+y/4-y/100+y/400(闰年调整))%
return h+1;//h+1是因为1582年以后蔡勒公式计算会少一天
}
}
//3.日历的输出
int runnian(int n)//记录闰年月份日期
{
switch(n)
{
case 1:return 31;
case 2:return 29;
case 3:return 31;
case 4:return 30;
case 5:return 31;
case 6:return 30;
case 7:return 31;
case 8:return 31;
case 9:return 30;
case 10:return 31;
case 11:return 30;
case 12:return 31;
}
}
int pingnian(int year,int month)//记录平年月份日期
{
if (year==1582&&month==10)
{
return 21;//1582年10月只有21天
}
switch(month)
{
case 1:return 31;
case 2:return 28;
case 3:return 31;
case 4:return 30;
case 5:return 31;
case 6:return 30;
case 7:return 31;
case 8:return 31;
case 9:return 30;
case 10:return 31;
case 11:return 30;
case 12:return 31;
}
}
void run(int week)//闰年日历输出
{
int n=0;//记录换行次数
int w=week;
for(int i=1;i<=12;i++)
{
printf("%d月\n",i);
printf("日 一 二 三 四 五 六\n") ;
for(int k=0;k<w;k++)//空格对齐
{
printf(" ");
n++;
}
for(int j=1;j<=runnian(i);j++){//输出每月的天
if(n%7==0){
printf("\n");
}
printf("%d ",j);
n++;
}
w=(w+runnian(i))%7;//周数
n=n-w;
printf("\n\n");
}
}
void ping(int year)//平年日历输出
{
int n=0;//记录换行
int w=getFirstDayOfYear(year);//获取该年第一天是星期几
for(int i=1;i<=12;i++)
{
printf("%d月\n", i);
printf("Sun Mon Tue Wed Thu Fri Sat\n");
for (int k=0;k<w;k++)
{
printf(" ");
n++;
}
for (int j=1;j<=pingnian(year,i);j++)
{//输出每月的天
if(n%7==0) // 七天换行
{
printf("\n");
}
printf("%d ",j);
n++;
}
w=(w+pingnian(year,i))%7;
n=n-w;
printf("\n\n");
}
}
//两个月的日历
void printTwoMonths(int year)
{
static int printed=0;//静态变量检测是否打印过日历
if(printed)
{
return;//如果打印过直接返回
}
int start_day[12];
start_day[0]=getFirstDayOfYear(year);
for (int month=1;month<12;month++)//计算每月起始星期几
{
start_day[month]=(start_day[month-1]+getDaysInMonth(year,month))%7;
}
const char *months[]={ "一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
for (int i=0;i<6;i++)
{
printf("\n");
for (int j=0; j < 2; j++)
{
int month=i*2+j+1;
printf(" %s %d ", months[month-1],year);
}
printf("\n");
for (int j=0;j<2;j++)
{
printf("Sun Mon Tue Wed Thu Fri Sat ");
}
printf("\n");
int max_days[2]={getDaysInMonth(year,i*2+1),getDaysInMonth(year,i*2+2)};//获取两个月的最大天数和起始星期几
int start_days[2]={start_day[i*2],start_day[i*2+1]};
//打印日期
int day[2]={1,1};//每个月的当前日期
int printed_anything=1;//标记是否有剩余日期可打印
while(printed_anything)
{
printed_anything=0;
for(int j=0;j<2;j++)
{
if(day[j]==1)//打印月初的空格
{
for(int k=0;k<start_days[j];k++)
{
printf(" ");
}
}
while(day[j]<=max_days[j]&&((day[j]+start_days[j]-1)%7)!=6) // 打印日期
{
printf(" %2d ",day[j]);
day[j]++;
printed_anything=1;
}
if(day[j] <= max_days[j]) // 打印最后一个日期,换行并跳到下一个月
{
printf(" %2d ",day[j]);
day[j]++;
printed_anything=1;
}
else
{
printf(" ");// 对齐
}
printf(" ");//每月之间的间隔
}
printf("\n");//换行到下一个星期
}
}
printed = 1; // 表示已经打印过日历
}
//4.菜单,设这个仅仅是为了能够返回,而且方便点。
void Menu1()
{
printf("请输入一个数字来表示你要进行的操作喵~\n");
printf("1.让我看看这年的日历吧~\n");
printf("2.我想看看这天是星期几捏?\n");
printf("3.我要看看这个年是不是闰年!\n");
printf("4.不看了nya\n");
}
int main()
{
int year,month,day,menu;
const char* week_days[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
while (1)
{
Menu1();//菜单选项
if(scanf("%d",&menu)!=1)//检查输入是否成功
{
while (getchar()!='\n');//清除输入缓冲区,这样输入中文就会返回了
printf("输入的格式不对,请重新输入:\n");
continue;
}
if(menu==1)
{
printf("你想看的形式是什么呢?输入以下数字查看相应方式。\n1.我要看单列输出!\n2.请给我看双列输出。\n");
int ds;
if(scanf("%d",&ds)!=1)//检查输入是否成功
{
while(getchar()!='\n');
printf("输入的格式不对,请重新输入:\n");
continue;
}
if(ds==1)//单列输出
{
printf("输入你想查询的年份吧:");
if (scanf("%d",&year)!=1)
{
while(getchar() != '\n');
printf("您输入的年份有误,请重新输入:\n");
continue;
}
if (year<1)
{
printf("您输入的年份有误,请重新输入:\n");
continue;
}
else
{
if (isLeapyear(year))
{
run(year);
}
else
{
if (year==1582)
{
ping(year);
}
else
{
ping(year);
}
}
}
}
else if(ds==2)//双列输出
{
printf("输入你想查询的年份吧: ");
if (scanf("%d",&year)!=1)//检查输入是否成功
{
while (getchar()!='\n');
printf("您输入的年份有误,请重新输入:\n");
continue;
}
if (year<=0)
{
printf("您输入的年份有误,请重新输入:\n");
continue;
}
int startDay=getFirstDayOfYear(year);
for (int i=1;i<12;i+=2)
{
printTwoMonths(year);
startDay=(startDay+(i==2?(isLeapyear(year)?29:28):(i==4||i==6||i==9?30:31)))%7;
}
}
else
{
printf("输入的格式不对,请重新输入:\n");
continue;
}
}
else if (menu == 2)
{
printf("请输入你想看的日期,格式是年-月-日哦:");
if (scanf("%d %d %d",&year,&month,&day)!=3)
{
while (getchar()!='\n');
printf("输入的日期有误,请重新输入:\n");
continue;
}
int weekday=week(year,month,day);
const char* week[]={"周日","周一","周二","周三", "周四","周五","周六"};
if (year<1||month<1||month>12||day<1||day>getDaysInMonth(year,month))
{
printf("输入的日期有误,请重新输入:\n");
continue;
}
else
{
printf("%d年%d月%d日是%s\n",year,month,day,week[weekday]);
}
}
else if (menu == 3)
{
printf("你想看看哪一年呢:");
if(scanf("%d", &year) != 1)
{
while(getchar() != '\n');
printf("输入的年份有误,请重新输入:\n");
continue;
}
if(year<1)
{
printf("输入的年份有误,请重新输入:\n");
continue;
}
else
{
printf("%d年%s是闰年哦\n",year,isLeapyear(year)?"":"");
}
}
else if(menu==4)
{
printf("加纳~\n");
return 0;//退出
}
else
{
printf("输入的格式不对,请重新输入:\n");
continue;
}
}
return 0;
}