寒假——万年历——答辩会

/*Univercity:烟台大学
*@Class</A>计134~4
*@Author:薛富磊
*@Time:2014-2-1
*@Function:实现万年历的功能,并以交互方式显示。适用于从公元 1 年 1 月 1 日至公元 9999 年之间的所有日期显示。
           输入某一年份,系统可输出该年年历,并保存为 *.txt 文件;
           输入某年某月可显示该月所有天数及每天所对应的星期;
           在屏幕上输入某一年、月、日,能够显示出星期几。
*@Args:
        1 、输入 / 输出人机界面交互。
        2 、逻辑表达式、条件控制语句、闰年 / 平年判断、全年天数计算等。
        3 、函数的调用、数组的使用、文件的操作。
        4 、掌握输出格式控制方法,实现对打印结果进行输出控制。
*@Return:
*/
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
int everyMonth[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//月份天数数组
class PC                       //创类和建对象
{
      public:
             void Input();//进行操作选择
             void SetDays();//如果输入某年,进行'3'操作处理
             void SetMonth();//如果选输入某年某月,进行'2'操作处理
             void SetYear();//如果输入某年某月某日,进行'1'操作处理
             bool IsLeap(int year);//判断是否是闰年
             bool IsRight(int year,int month,int day);//判断输入是否合法
             int GetDays(int year,int month,int day);//得到此日期前(从1年1月1号还是算)的天数
             void Print(int year,int month);//输出到界面上
             void Output(int year); //打印到文档out,一年的
};

//进行操作选择的自定义函数
void PC::Input()
{
     char choose;
     bool flag=true;
     while(flag)
    {
     cout<<"---------------欢迎使用万年历---------------------"<<endl;
     cout<<"|                                                |"<<endl;
     cout<<"|请选择: (1/2/3/4/else)                          |"<<endl;
     cout<<"|                                                |"<<endl;
     cout<<"|1:      输入某年,显示该年的年历                |"<<endl;
     cout<<"|                                                |"<<endl;
     cout<<"|2:      输入某年某月,显示该月的万年历          |"<<endl;
     cout<<"|                                                |"<<endl;
     cout<<"|3:      输入某年某月某日,显示该日是星期        |"<<endl;
     cout<<"|                                                |"<<endl;
     cout<<"|4:             退出                             |"<<endl;
     cout<<"--------------------------------------------------"<<endl;
     cout<<"输入您的选择: ";
     cin>>choose;
          switch(choose)
          {
                   case '1':SetYear();break;
                   case '2':SetMonth();break;
                   case '3':SetDays();break;
                   case '4':flag=false;break;
                   default:cout<<"输入错误,请重新输入:\n";
          }
    }
}
//判断输入是否合法的自定义函数
bool PC::IsRight(int year,int month,int day) //判断日期输入是否正确
{
       if(year<1 || year>9999 || month<1 || month>12)//年月是否正确
          return false;
 //日期是否正确
       if(day<0)return false;
       else if( day==29)
           return((month==2 && IsLeap(year))|| month!=2);
       else if(day==31)
           return(month==1 ||month==3 ||month==5 ||month==7 ||month==8 || month==10 || month==12);
       else if(day>31) return false;
       else return true;
 }
//如果输入某年某月某日,进行'1'操作处理
void PC::SetDays()
{
   int weekDay;
     int year,month,day;
     cout<<"           请输入年_月_日:";
     cin>>year>>month>>day;

     while(!IsRight(year,month,day))     //判断输入是否正确
     {
         cout<<"输入错误,请重新输入年_月_日:";

          cin>>year>>month>>day;
     }

     weekDay=GetDays(year, month,day)%7;//根据已经过的日子和求余得星期

     switch(weekDay)//输出
     {
              case 0: cout<<year<<"年"<<month<<"月"<<day<<"日  星期日"<<endl; break;
              case 1: cout<<year<<"年"<<month<<"月"<<day<<"日  星期一"<<endl; break;
              case 2: cout<<year<<"年"<<month<<"月"<<day<<"日  星期二"<<endl; break;
              case 3: cout<<year<<"年"<<month<<"月"<<day<<"日  星期三"<<endl; break;
              case 4: cout<<year<<"年"<<month<<"月"<<day<<"日  星期四"<<endl; break;
              case 5: cout<<year<<"年"<<month<<"月"<<day<<"日  星期五"<<endl; break;
              case 6: cout<<year<<"年"<<month<<"月"<<day<<"日  星期六"<<endl; break;
      }

}
//判断是否是闰年的自定义函数
bool PC::IsLeap(int year)
{
    return ((year%4==0 && year%100!=0)||(year%400==0));
 }

//得到此日前所有已经过的日子的自定义函数
int PC::GetDays(int year,int month,int day)
{
     int yearDays, monthDays,sum;
     int accumulate=0;                // accumulate代表闰年数
     for(int i=1;i<year;i++)
        if(IsLeap(i))
         accumulate++;                // 求闰年数
    yearDays=accumulate+365*(year-1);//经过整年的日子数(闰年366)

    if((year%4==0 && year%100!=0)||(year%400==0))   everyMonth[2]=29;//如果是闰年,则2月为29天

     for(int j=0;j<month;j++)
         monthDays+=everyMonth[j];//当年经过整月的日子数

    sum=yearDays+monthDays+day;//所有已经过的日子之和
    return sum;
 }
//当输入的是年月时,进行'2'操作处理
void PC::SetMonth()
{
     int year,month,day;
     cout<<"           请输入年_月:";
     cin>>year>>month;
     day=1;

      while(!IsRight(year,month,day))//判断输入是否正确,设置day=1
     {
         cout<<"输入错误,请重新输入年_月:";
          cin>>year>>month;
     }
     Print(year,month);      //调用打印该月月历
}
//当输入的是年时,进行'1'操作处理
void PC::SetYear()
{
     int year,month,day;
     cout<<"           请输入年:";
     cin>>year;
     month=1;day=1;

     while(!IsRight(year,month,day))//判断是否输入正确,若错误,请重新输入 .设置day=1,month=1,
     {
         cout<<"输入错误,请重新输入年:";
         cin>>year;
     }

     cout<<"万年历打印在out文档中,请查看。"<<endl;
     Output(year);

    for(int k=1;k<=12;k++)//将12个月的万年历在界面上输出
      Print(year,k);
}
//打印到界面上的自定义函数
void PC:: Print(int year,int month)
{
     int weekday,day=1;
     cout<<"            公元"<<year<<"年"<<month<<"月"<<endl;
     cout<<"     SUN   MON   TUE   WES   THU   FRI   SAT"<<endl;
     weekday=(GetDays(year, month,day)+4)%7;//所有的日期之和取余
      switch(weekday)//输出处理”不同月份1号对应的星期“
     {
             case 0: cout<<"     "<<setw(6)<<setiosflags(ios::left)<<"1"; break;
             case 1: cout<<"           "<<setw(6)<<setiosflags(ios::left)<<"1";break;
             case 2: cout<<"                 "<<setw(6)<<setiosflags(ios::left)<<"1";break;
             case 3: cout<<"                       "<<setw(6)<<setiosflags(ios::left)<<"1";break;
             case 4: cout<<"                             "<<setw(6)<<setiosflags(ios::left)<<"1";break;
             case 5: cout<<"                                   "<<setw(6)<<setiosflags(ios::left)<<"1";break;
             case 6: cout<<"                                         "<<setw(6)<<setiosflags(ios::left)<<"1";break;
     }

  for(int i=2;i<=everyMonth[month];i++)//输出2号以后的
  {
     weekday=(++weekday)%7;
     if(!weekday)
         {cout<<endl; cout<<"     "<<setw(6)<<setiosflags(ios::left)<<i;}
     else
           cout<<setw(6)<<setiosflags(ios::left)<<i;
   }
    cout<<endl;
}
//打印到out文本框内的自定义函数
void PC::Output(int year)
{
      int weekday,month=1,day=1;
      int i,j;
    /*创建一个输出文件流对象outfile,输出文件为程序所在文件夹中的名为out.txt的文件。
    以后可以使用outfile对象将数据输出到文件out.txt中(如同使用cout将数据输出到屏幕一样)*/
     ofstream outfile("out.txt",ios::out);
     for(i=1;i<=12;i++)
    {
     outfile<<"            公元"<<year<<"年"<<i<<"月"<<endl;
     outfile<<"     SUN   MON   TUE   WES   THU   FRI   SAT"<<endl;
     weekday=(GetDays(year, i,day)+4)%7;
      switch(weekday)
     {
              case 0: outfile<<"     "<<setw(6)<<setiosflags(ios::left)<<"1"; break;
              case 1: outfile<<"           "<<setw(6)<<setiosflags(ios::left)<<"1";break;
              case 2: outfile<<"                 "<<setw(6)<<setiosflags(ios::left)<<"1";break;
              case 3: outfile<<"                       "<<setw(6)<<setiosflags(ios::left)<<"1";break;
              case 4: outfile<<"                             "<<setw(6)<<setiosflags(ios::left)<<"1";break;
              case 5: outfile<<"                                   "<<setw(6)<<setiosflags(ios::left)<<"1";break;
              case 6: outfile<<"                                         "<<setw(6)<<setiosflags(ios::left)<<"1";break;
      }
        for( j=2;j<=everyMonth[i];j++)
       {
              weekday=(++weekday)%7;
              if(!weekday)
                  {outfile<<endl; outfile<<"     "<<setw(6)<<setiosflags(ios::left)<<j;}
              else
                   outfile<<setw(6)<<setiosflags(ios::left)<<j;
        }

      outfile<<endl;
      outfile<<endl;

     }
     cout<<endl;
     outfile.close();
}

//主函数
int main()
{
    PC pc;
    pc.Input();
}

         









心得体会:

                  不容易呀

                  计算输出年历的地方有个问题

                  weekday=(GetDays(year, i,day)+4)%7

                理论来讲应该 weekday=(GetDays(year, i,day))%7可是不对

                WHY?????????????????????????

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值