/*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?????????????????????????