C++万年历课程设计

C++课程设计——万年历

功能要求:
(1)输入一个年份,输出是在屏幕上显示该年的日历。假定输入的年份在1940-2040年之间。
(2)输入年月,输出该月的日历。
(3)输入年月日,输出距今天还有多少天,星期几,是否是公历节日。

一.设计目的

1:要求学生能够熟练掌握C++语言的基本知识和技能。
2:基本掌握面向过程程序设计的基本思路和方法。
3:能够利用所学的基本知识和技能,解决简单的面向过程程序设计问题。
4:培养自己独立分析问题、解决问题、查阅资料以及自学能力,综合运用所学知识,解决实际问题,提高程序设计能力和开发能力。

二.总体设计

设计程序框图,明白整体过程的理解和思路

三.详细设计

(1)函数功能:判断是平年,还是润年
函数原型:int nyear(int year);
参数:year;
返回值:365||366;
(2)函数功能:根据年份和月份,判断是那一个月的天数
函数原型:int nmonth(int m,int y);
参数:m,y;
返回值:31,30,29,28;
(3)函数功能:输入年份和月份确定到1940年1月1日总共多少天
函数原型:int getDays(int year, int month);
参数:year,month;
返回值:sum(总天数);
(4)函数功能:输入年份和月份和日子确定到1940年1月1日总共多少天
函数原型:int getDays0(int year, int month,int t);
参数:year,month,t;
返回值:sum+t;
(5)函数功能:输出一年的日期
函数原型:void wnl1(int year)
参数:year
(6)函数功能:输出某年某月的日历
函数原型:void wnl2(int year,int month)
参数:year,month
(7)函数功能:求时间间隔,并判断是不是公历节日,星期几
函数原型:void wnl3(int m_year,int m_month,int m_day,int cz)
参数 m_year,m_month,m_day,cz
(8)循环
对于一般的循环,若不符合条件直接跳出;
do-while 循环中,第一次使用之后,若输入字符y或者Y可重新循环,输入其他字符就跳出循环,实现万年历功能多次使用
(9)switch语句
可以列一个功能清单,输入1/2/3便进入相应的功能区,同时在case里面可以写一些不方便计算的数值以此作为实参进入函数体中,或者直接输入实参进入函数体

四.调试与测试

功能1:输入一个年份,输出该年份的日期

功能2:输入一个年月,输出该年月的日历显示
功能3:输入两个日期,并计算差值

五.实现方法:(源程序)

#include "StdAfx.h"
#include<iostream>
using namespace std;
//1940年1月1号是星期一
int nyear(int year)//判断是平年,还是闰年
{
	if(year%400==0||(year%4==0&&year%100!=0))
	   return 366;
   else
	   return 365;
}
 
int nmonth(int m,int y)  //根据年份和月份,判断那一个月的天数
{
   if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
	   return 31;
   else if(nyear(y)==366&&m==2)
	   return 29;
   else if(nyear(y)==365&&m==2)
	   return 28;
   else
	   return 30;
}
int getDays(int year, int month)//输入年份和月份确定到1940年1月1日总共多少天,1940.1.1是星期一
{
   int i;
   int sum=0;
   if(year>1940)
      for(i=1940;i<year;i++)
    	  sum+=nyear(i);//此时sum为1940——year-1年的天数
   if(month>1)
      for(i=1;i<month;i++)
    	  sum+=nmonth(i,year);
   return sum;     //返回上个月末距离1940.1.1的总天数
}
 int getDays0(int year, int month,int t)//输入年 月 日确定到1940年1月1日总共多少天
{
   int i;
   int sum=0;
   if(year>1940)
      for(i=1940;i<year;i++)//此时sum为1940——year-1年的天数
    	  sum+=nyear(i);
  if(month>1)
      for(i=1;i<month;i++)
    	  sum+=nmonth(i,year);//上个月末到1940.1.1的天数,还差本月某日的天数
   return sum+t;//t为当然月份的日历号数,此时sum+t即为1940——输入时间 的总天数
}
  void wnl1(int year)//输出一年的日期
{
      int month,daycount,k,sum,t,j;
	  char *t_month[13] = {0,"一月(Jan)","二月(Feb)","三月(Mar)","四月(Apr)","五月(May)","六月(Jun)","七月(Jul)","八月(Aug)","九月(Sep)","十月(Oct)","十一月(Nov)","十二月(Dec)"};
	  char *t_week[7] = {"Sun","Mon","Tue","Wen","Thru","Fri","Sat"};
		for( month=1; month<=12; month++)//年循环,输出每年的每月
       {    
		 cout<<endl;
		 cout<<endl;
		 cout<<endl;
		 cout<<"            "<<t_month[month]<<endl;	
		 cout<<"☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆"<<endl;
		 cout<<"Sun   Mon   Tue   Wed   Thu   Fri   Sat"<<endl;
		 sum=getDays( year, month);
		 t=sum%7+1;//sum/7所得的整数表示轮回了多少个星期,所得的余数是已经过去了几天,+1是因为一般日历一周显示是从周日到周六,若日历表示从周一到周日,即不需要+1,但要注意每月一号前需要几个空格数
		 daycount=nmonth(month,year);//算出这个月的天数
		 if(t<7)
		 {for(j=0;j<t;j++)
         cout<<"      ";}//输出空格,找出每月1号是星期几。星期日是第一个,所以前面不需要空格
		  for(k=1;k<=daycount;k++)//开始循环,输出每月的天数
			{  t++; //因为格式要对齐,所以要用空格来对齐
		        if(k<10)
                cout<<k<<"     ";
                 if(k>=10)    
		         cout<<k<<"    ";
		         if(t%7==0)
				  cout<<endl;
		     }
		  cout<<endl;
		 }
		 cout<<endl;
}
void wnl2(int year,int month)
{
   int i,j,day,sum,daycount;
      sum=getDays(year,month);
      day=sum%7+1;  //这里算出来这个月的一号前面需要几个空格;等于0的话,前面就不需要空格
      daycount=nmonth(month,year);//算出这个月的天数
	  cout<<endl;
      cout<<"☆☆★☆☆★☆ "<<year<<"年"<<month<<"月"<<" ☆★☆☆★☆☆"<<endl;
	  cout<<endl;
      cout<<"Sun   Mon   Tue   Wed   Thu   Fri   Sat"<<endl;
	   if(day<7)
		 {for(j=0;j<day;j++)
         cout<<"      ";}
      for(i=1,j=day+1;i<=daycount;i++,j++)//开始循环,输出每月的号
      {    
		   //因为,格式要对齐,所以要用空格来对齐
             if(i<10)
                cout<<i<<"     ";
	        if(i>=10)
				 cout<<i<<"    ";
         if(j%7==0) 
			 cout<<endl;
      }
      cout<<endl;
	   cout<<endl;
   }
void wnl3(int m_year,int m_month,int m_day,int cz)
{   char m[8][50]={"周日","周一","周二","周三","周四","周五","周六"};
     int i,j;
	j=getDays( m_year,m_month);//计算当前时间的上个月末到1940.1.1的总天数差
	 i=((j%7)+m_day%7)%7;//j/7与m_day/7所得整数部分表示轮回了多少个星期,所得余数部分表示两个零碎的时间段,可能大于或者小于或者等于7,再%7即表示当前是星期几
	   cout<<"                                 "<<endl;
	   cout<<"☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆"<<endl;
	 if(cz>=0)
	 cout<<"        期间相差:"<<cz<<endl;
	 else 
		 cout<<"        期间相差:"<<(-1)*cz<<endl;//因为某一天 的日期可能小于当前时间,但是时间间隔不可能为负数,所以所得时间*(-1)即正数
	  cout<<"                                 "<<endl;
	 while(m_month,m_day)//判断某一的日期是否是公立节日,如果是输出某一天的公立节日,如果不是,则判断下一个
	 //一月一日,元旦 
	 { if (m_month==1&&m_day==1)
	cout<<"☆☆☆   "<<m[i]<<"   ★   "<<"元旦   ☆☆☆\n";
	  //2月十四,情人节
	else if (m_month==2&&m_day==14)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"情人节  ☆☆☆\n";
	  //三月八日,妇女节
	else  if(m_month==3&&m_day==8)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"妇女节  ☆☆☆\n";
	  //三月十二,植树节
	else if(m_month==3&&m_day==12)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"植树节  ☆☆☆\n";
	//四月一日,愚人节
	else if(m_month==4&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"愚人节  ☆☆☆\n";
	  //五月一日,劳动节
	else if(m_month==5&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"劳动节  ☆☆☆\n";
	  //五月四日,青年节
	else  if(m_month==5&&m_day==4)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"青年节  ☆☆☆\n";
	  //六月一日,儿童节
	else  if(m_month==6&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"儿童节  ☆☆☆\n";
	  //七月一日,建党节
	else if(m_month==7&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"建党节  ☆☆☆\n";
	  //七月七日,七夕节·
	else if(m_month==7&&m_day==7)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"七夕节  ☆☆☆\n";
	  //八月一日,建军节
	else if(m_month==8&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"建军节  ☆☆☆\n";
	  //九月十日,教师节
	else if(m_month==9&&m_day==10)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"教师节  ☆☆☆\n";
	  //十月一日,国庆节
	else  if(m_month==10&&m_day==1)
	cout<<"☆☆☆  "<<m[i]<<"   ★   "<<"国庆节  ☆☆☆\n";
	else
	cout<<"☆☆  "<<m[i]<<"  ★  "<<"不是公历节日  ☆☆\n";
	break;
	 }
	  cout<<"☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆"<<endl;
  }
void main()
{
	int a,year,month,day,year1,month1,day1,k1,k2,cz;
	   	char m;
	cout<<endl;
    cout<<"☆☆☆☆☆☆☆☆☆☆☆ 欢迎使用万年历 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆ ";
	cout<<endl;
	cout<<endl;
	do
	{
		cout<<"☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆"<<endl;
		cout<<"★                                                              ★"<<endl;
		cout<<"☆       1.输入一个年份,并显示该年的日历.(1940~2040)           ☆"<<endl;;
		cout<<"★                                                              ★"<<endl;
		cout<<"☆       2.输入年月,输出该月的日历                              ☆"<<endl;
		cout<<"★                                                              ★"<<endl;
		cout<<"☆       3.计算两个日期的时间间隔                               ☆"<<endl;
		cout<<"★                                                              ★"<<endl;
		cout<<"☆       4.退出                                                 ☆"<<endl;
		cout<<"★                                                              ★"<<endl;
		cout<<"☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆"<<endl;
		cout<<endl;
		cout<<"            请输入你要进行的操作:";
		cin>>a;
	switch(a)
	{
	case 1:
		cout<<"           请输入1940~2040期间的年份"<<endl;
		cin>>year;
		cout<<endl;
		wnl1(year);
	break;
	case 2:
	   	 cout<<"请输入查询的年份  月份"<<endl;
	   	  cin>>year>>month;
		  wnl2(year,month);break;
	case 3:
		  cout<<"请输入今天的日期,年  月  日"<<endl;
	 cin>>year>>month>>day;
	k1= getDays0( year,month,day) ;//计算1940.1.1——year.month.day的天数差
	   cout<<"请输入某一天的日期,年  月  日"<<endl;
	 cin>>year1>>month1>>day1;
	k2= getDays0( year1,month1,day1) ;//计算1——的天数差
	cz=k1-k2;/*    以1940.1.1为基准,两个日期分别与该日期取时间差,相减所得即为两个日期的时间间隔
	 数学表达式为:(year.month.day-1940.1.1)-(year1.month1.day1-1940.1.1)=(year.month.day)-(year1.month1.day1)   */
	wnl3(year1,month1,day1,cz);
	default:
		break;
	}
	cout<<"您要继续查询吗?    (Y/ N)"<<endl;
	cin>>m;
	}
   while(m=='y'||m=='Y') ;//控制该程序要不要继续循环
   	cout<<endl;
	cout<<"     ☆★☆ 谢谢您的使用 ☆★☆"<<endl;
	cin.get();
	cin.get();
}

六.课程设计总结

针对整个课程设计过程进行一个总结,比如过程中遇到的问题与解决办法,程序编写,调试运行过程与体会等。
总结:
(1):首先判断这一年是否为闰年,其次确定该年的每个月的天数;
(2):找到规律1900年的1月1日是周一,所以总天数/7所得的整数表示轮回了多少个星期,所得的余数是已经过去了几天,(+1是因为一般日历一周显示是从周日到周六,若日历表示从周一到周日,即不需要+1),但要注意每月一号前需要几个空格数余7,再加1就是星期几;按照此规律找到以后每一年每一月的1号星期几,然后利用循环打出每个月的日历,其中要注意每到周日要换行,所以定义t为每月的一号星期几,然后t%7==0时,换行,这样保证号与星期对上;
(3):每个日子之间要有空格,使它们的格式相同;同时需要计算每月一号是星期几,然后再计算前面需要多少空格;
(4):一维char型数组只能存一组字符串,二维可存多组字符串;
(5):计算某天是星期几的时候,要进行分步计算,利用getDays算出上个月末距离1940.1.1的天数,再加上输入的日期在该月过了多少天,所得的总天数除以7所得余数就是星期几;
(6)计算时间差值可以定一个基准,分别求出两次输入的时间与该基准相隔的天数k1和k2,差值即为k1-k2,其数学表达式为:(year.month.day-1940.1.1)-(year1.month1.day1-1940.1.1)=(year.month.day)-(year1.month1.day1)=cz。

问题
(1)变量比较多,有时候会忘记哪个是哪个;
(2)循环和条件if语句中很容易忘记{}的使用,导致莫名其妙的失误;
(3)对问题的解题思路有点迷茫,不知道如何去想每一个月的一号前面为什么空出来了,某天是星期几,时间间隔怎么计算;
(4)形参的个数有时候不统一,有时候不知道如何引用实参;
(5)对循环结束的条件不明确,导致进入死循环。

  • 52
    点赞
  • 341
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A十点差三分

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值