万年历
来源:互联网 发布:js只让页面刷新一次 编辑:程序博客网 时间:2024/05/22 14:31
#include<iomanip>
using namespace std;
class Date
{
private:
int year;
int month;
int day;
public:
Date(int y = 1, int m = 1, int d = 1): year(y), month(m), day(d){ }
void SetYear(int y){ year = y; }
void SetMonth(int m){ month = m;}
void SetDay(int d){ day = d; }
int GetYear() const{ return year; }
int GetMonth() const{return month;}
int GetDay() const{ return day; }
static bool IsLeapyear(int y);
static int GetYearDays(int y);
static int GetMonthDays(const Date &d);
static int DateToNum(const Date &d);
static int Week(const Date &d);
};
ostream &operator<<(ostream &out, const Date &d);
istream &operator>>(istream &in, Date &d);
bool Date::IsLeapyear(int y)
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) return true;
else return false;
}
int Date::GetYearDays(int y)
{
if (IsLeapyear(y)) return 366;
else return 365;
}
int Date::GetMonthDays(const Date &d)
{
int n;
switch (d.GetMonth())
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
n = 31;
break;
case 4:
case 6:
case 9:
case 11:
n = 30;
break;
case 2:
if (IsLeapyear(d.GetYear())) n = 29;
else n = 28;
}
return n;
}
int Date::DateToNum(const Date &d)
{
int y, n = 0;
for (y = 1900; y < d.GetYear(); y++)
n += GetYearDays(y);
for (int m = 1; m < d.GetMonth(); m++)
n += GetMonthDays(Date(y, m, 1));
n += d.GetDay();
return n;
}
ostream &operator<<(ostream &out, const Date &d)
{
int i,j,n,m;
m=1;
out<<endl;
out<<setw(10)<<"星期天"
<<setw(10)<<"星期一"
<<setw(10)<<"星期二"
<<setw(10)<<"星期三"
<<setw(10)<<"星期四"
<<setw(10)<<"星期五"
<<setw(10)<<"星期六"<<endl;
out<<endl;
for(j=0;j<d.Week(d);j++)
{
out<<setw(10)<<" ";
}
for(j=0;j<7-d.Week(d);j++)
{
out<<setw(10)<<m;
m++;
}
out<<endl;
n=m;
i=0;
while(n<=(d.GetMonthDays(d)))
{
i++;
out<<setw(10)<<n;
n++;
if(i%7==0)
out<<endl;
}
out<<endl;
return out;
}
int Date::Week(const Date &d)
{
int w;
w=(Date::DateToNum(d)-1+1)%7;
return w;
}
int main(void)
{
int s;
int year,month,day;
char m[][5]={"一","二","三","四","五","六","七","八","九","十","十一","十二"};
Date d;
cout <<"输入年份:";
day=0;
month=0;
cin >> year;
cout<<setw(38)<<year<<"年"<<endl;
for(s=0;s<12;s++)
{
month++;
d = Date(year,month,1);
cout<<" ==================================================================== "<<endl;
cout<<setw(35)<<"<* "<<m[s]<<setw(3)<<"月"<<" *>"<<endl;
cout<<d<< endl;
}
return 0;
}
第二个程序:::::
#include<iostream.h>
#include<math.h>
int year,month,error,n=1,m=2010,day,monthdays,xiayibu;
void rili(int c,int d);
int yearways(int g);
int monthways(int k);
void main()
{
cout<<"\t\t\t\t欢迎使用万年历\n\n\n";
cout<<"请输入您所要查看的年份和月分:";
error:cin>>year>>month;
if(year<2010||month<1||month>12)
{
cout<<"输入错误,请重新输入:";
goto error;
}
cout<<"\t\t\t\t"<<year<<"年"<<month<<"月"<<"\n"<<"\t日\t一\t二\t三\t四\t五\t六"<<"\n";
rili(year,month);
}
int yearways(int g)
{
int exdays,yihangdays=0;
for(int i=2010;i<=year;i++)
{
if(i%400==0||i%4==0&&i%100!=0)
exdays=2;
else
exdays=1;
yihangdays+=4+exdays;
}
day=yihangdays%7;
return day;
}
int monthways(int k)
{
yearways(year);
int zongdays=0;
for(int i=1;i<month;i++)
{
switch(i)
{
case 1:
case 5:
case 3:
case 7:
case 8:
case 10:
case 12:monthdays=31;
break;
case 4:
case 6:
case 9:
case 11:monthdays=30;
break;
case 2:
if(year%400==0||year%4==0&&year%100!=0)
monthdays=29;
else
monthdays=28;
break;
}
zongdays=monthdays+day;
day=zongdays%7;
}
return day;
}
void rili(int c,int d)
{
monthways(month);
d=8-day;
for(int i=1;i<=9-d;i++)
cout<<"\t";
for( i=1;i<d;i++)
cout<<i<<"\t";
cout<<"\n\t";
for(int s=2;s<=6;s++)
{
for(int a=1;a<=14;a++)
{
cout<<d<<"\t";
d++;
a++;
switch(month)
{
case 1:
case 5:
case 3:
case 7:
case 8:
case 10:
case 12:monthdays=31;
break;
case 4:
case 6:
case 9:
case 11:monthdays=30;
break;
case 2:
if(year%400==0||year%4==0&&year%100!=0)
monthdays=29;
else
monthdays=28;
break;
}
if(d>monthdays)
goto xiayibu;
}
cout<<"\n"<<"\t";
}
xiayibu:cout<<"谢谢";
}
万年历的设计与实现
摘 要:设计一个万年历的程序代码,时间是从1800年到2050年。在这个时间段,无论输入何年何月,只要是不超出这个时间段,都可以显示出那一年份的日历。并且在万年历范围内平年、闰年均能正常显示,能准确判断每一个月是大月还是小月,并能够准确判断每个月的第一天是星期几。
1.题目与要求
显示1800年-2500年之间任何年份的日历,日历以月份顺序排列,每月以星期顺序排列,类似于一般挂历上的格式。
2.结构设计
图1 整体结构图
2.1 Data类的构建
构建一个Data类,其中包含一个数据成员,用于存放查询年。另外包括5个成员函数,分别用于获得并判断查询年数据,判断查询年是否为闰年,判断查询年的元旦时星期几,判断任何一年的每个月分别有几天和输出结果。
2.2 数据输入与判断
利用输入流获得要查询的年份,并判断该年是否在查询范围内。如不在则要求重新输入,并判断当年是不是闰年。
2.3 元旦判断与闰年判断
利用一定的公式与算法来判断查询年是否为闰年,并且从参照年到查询年一共经过了多少天,从而得到查询年的元旦时星期几。
2.4 每月天数判断
根据大小闰月的不同返回当前月的天数。
2.5 结果输出
按一定格式输出查询年全年的日历,按周日——周六排列。
3.关键算法分析
3.1 int Date::ytm(int n) //n代表输入的年份
{
int m=0;
for(int i=1798;i<n;i++) //1798的1月1日是星期天
{
if(getyear(i)) m+=2; //如果是闰年则m加2
else m+=1; //如果是平年则m加1
}
m=m%7; //将1798到(n-1)年多出来的总天数除7取余,就得到n年的第一天前面应该空几格。
return m;
}
bool Date::getyear(int m)
{ if(m%4==0&&m%100!=0||m%400==0) return true;
else return false;
}
其中getyear()函数是判断这一年是平年还是闰年(能被4整除、
100整除货被400整除的是闰年)。并且返回真假值。
void ytm1(int x)
{ int y,s,gs;
Date d; d.set(x);
y=d.ytm(x);
s=y; // x年的第一天前面应该空s格
for(int i=1;i<13;i++) //一年为12月,
{ cout<<"---------------------------------------------------------" <<endl;
gs=d.sw(i,d);
s%=7; //判断每一月的第一天前应该有几个’\t’
for(int j=1;j<=gs;j++) //循环输出这一月的每一天
{
if(j==1&&i!=1) //判断每一月的第一天是星期几
{
for(int a=1;a<=s;a++)
{cout<<"\t";}
}
if(i==1&&j==1) //判断这一年的第一天是星期y
{
for(int c=0;c<y;c++)
{ cout<<"\t";}
}
cout<<" "<<j<<"\t";
if((j+s)%7==0) //判断每一个星期为7天
cout<<endl;
}
cout<<endl;
s+=gs; //s加上每一个月的天数
}
cout<<"-----------------------------------------------------------"<<endl;
}
4.设计实现
int main()
{
int x,gs,y,s=0;
cout<<"请输入要查询的年份(1800-2500):";
cin>>x;
cout<<"\t\t\t"<<x<<"年"<<endl;
if(x<1800||x>2500) // 判断输入的年数是否在1800-2500內
{cout<<"输入错误";
return 0;}
ytm1(); // 输出这一年的日历。
return 0;
}
5.测试
经测试,程序能正常显示1800-2500年之间任何一年的日历,输入超范围数据将会提示重新输入。
(1)测试:程序运行
图1 程序运行结果图
(2)测试数据:1800年
图2 1800年运行结果图
(3)测试数据:2008年
图3 2008年运行结果图
(4)测试数据:1781年
图4 1781年运行结果图
6.总结
在程序设计过程中,更加熟练的运用了公有函数和私有函数,并且掌握了写实验报告的格式,在编程和写实验报告的过程中遇到了很多的问题,任然坚持编写,并且在多人合作下完成,感到了团结就是力量。
由于对C++课程的不熟悉,导致对编写万年历程序代码时根本无从这手。如果不是参考书目,或是上网查找资料的话,根本不可能完成这次报告的编写。让我体会到我在C++学习方面还有很多的不足之处,以后一定会加紧学习。
参考书目
[1]游鸿跃,伍良富,王景熙.C++面向对象程序设计实验和课程设计教程[M].北京:清华大学出版社,2009.2
附录:
#include<iostream.h>
class Date
{ private:
int year;
public:
void set(int a){year=a;}
bool getyear(int m);
int sw(int m,const Date &d);
int getyeardays(int y);
int Date::ytm(int n);
};
int Date::getyeardays(int y)
{ if(getyear(y)) return 366;
else return 365;
}
bool Date::getyear(int m)
{ if(m%4==0&&m%100!=0||m%400==0) return true;
else return false;
}
int Date::ytm(int n)
{
int m=0;
for(int i=1798;i<n;i++)
{
if(getyear(i)) m+=2;
else m+=1;
}
m=m%7;
return m;
}
int Date::sw(int m,const Date &d)
{ int n;
static k=0;
switch(m)
{
case 1:cout<<"\t\t\t一月"<<endl;n=31;break;
case 3:cout<<"\t\t\t三月"<<endl;n=31;break;
case 5:cout<<"\t\t\t五月"<<endl;n=31;break;
case 7:cout<<"\t\t\t七月"<<endl;n=31;break;
case 8:cout<<"\t\t\t八月"<<endl;n=31;break;
case 10:cout<<"\t\t\t十月"<<endl;n=31;break;
case 12:cout<<"\t\t\t十二月"<<endl;n=31;break;
case 4:cout<<"\t\t\t四月"<<endl;n=30;break;
case 6:cout<<"\t\t\t六月"<<endl;n=30;break;
case 9:cout<<"\t\t\t九月"<<endl;n=30;break;
case 11:cout<<"\t\t\t十一月"<<endl;n=30;break;
case 2:
if(getyear(d.year))
{cout<<"\t\t\t二月"<<endl;n=29;break;}
else
{cout<<"\t\t\t二月"<<endl;n=28;break;}
}
cout<<endl<<"星期一"<<"\t星期二"<<"\t 星期三"
<<"\t 星期四"<<"\t 星期五"<<"\t 星期六"
<<"\t 星期日"<<endl;
return n;
}
void ytm1(int x)
{ int y,s,gs;
Date d; d.set(x);
y=d.ytm(x);
s=y;
for(int i=1;i<13;i++)
{ cout<<"---------------------------------------------------------------"<<endl;
gs=d.sw(i,d);
s%=7;
for(int j=1;j<=gs;j++)
{
if(j==1&&i!=1)
{
for(int a=1;a<=s;a++)
{cout<<"\t";}
}
if(i==1&&j==1)
{
for(int c=0;c<y;c++)
{ cout<<"\t";}
}
cout<<" "<<j<<"\t";
if((j+s)%7==0)
cout<<endl;
}
cout<<endl;
s+=gs;
}
cout<<"---------------------------------------------------------------"<<endl;
}
int main()
{
int x;
cout<<"请输入要查询的年份(1800-2500):";
cin>>x;
if(x<1800||x>2500)
{cout<<"输入错误"<<endl;
return 0;
}
cout<<"\t\t\t"<<x<<"年"<<endl;
ytm1(x);
return 0;
}