万年历

来源:互联网 发布:js只让页面刷新一次 编辑:程序博客网 时间:2024/05/22 14:31
#include <iostream>
#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;

}

 


0 0