山东交通学院面向对象课程设计万年历系统目录1课程设计概述 (5)1.1 万年历系统功能概述 (5)1.2 开发环境概述 (5)2万年历系统总体设计 (6)2.1 问题分析 (6)2.2 总体设计流程图 (7)3万年历系统详细设计 (8)4 程序测试 (9)4.1 进入程序界面 (9)4.2 主菜单界面 (9)4.3 显示当前时间界面 (10)4.4 查询时间界面 (10)4.5查询时间出错界面 (11)4.6退出程序界面 (12)4.7主菜单选择出错界面........................................................................ 错误!未定义书签。
25 程序源代码 (13)设计体会及今后的改进意见 (21)参考文献 (21)1课程设计概述1.1字符统计软件功能概述模仿Windwos的日历.1)日历显示功能。
能根据系统日期进行初始化,如果没有任何输入,则显示系统日期所在月份的月历。
2)日历查询、闰年判断功能。
输入日期进行查询,显示查询日期所在月份的月历,还将显示所在年份是否为闰年。
3)参数检查功能。
如果输入日期不合法,查询将被拒绝,并显示提示信息。
1.2开发环境概述在实验室一人一台微机。
2课程设计概述2.1问题分析2.1.1难点在于判断星期,但根据蔡勒公式,可以很容易地有年月日推断出星期:nDay=year-1+(year-1)/4-(year-1)/100+(year-1)/400+nday;w=nDay%7;其中year:要查询的年份nday:从该年的一月一日起到该天的天数w:得出的星期数,w==0表示星期天。
2.1.2在打印月历时,只要知道第一天的星期,就可以依次输入后面的日期,通过定长度输出日期,在遇到某天时星期六时,就换行输出,因此可以按照月历的格式输出。
对于初始输入当前月历,可以通过<time.h>中的time 和localtime 函数取出系统时间进行初始化。
time_t timer;struct tm* gmt;time(&timer);gmt=localtime(&timer);gmt就是一个时间结构体,可以从中取出年月日。
2.1.3闰年的判断,能被4整除但不能被100整除,或者能被400整除的年份为闰年,否则为平年。
日期的查询,就是直接打印该天所在月份的月历。
2.1.4判断日期是否合法,可以先判断年月日是否有小于0的值,月和日是否有超出最大值12和31 ,如果通过此判断合法,再判断是否时闰年,如果时闰年,则判断二月份是否满足要求,闰年二月份不能超过29天,平年二月份不能超过28天。
在查询过程中,如果发现输入不合法或者不满足输入要求,则要求重新输入。
2.2总体设计流图2.2.13万年历系统详细设计3.1.1int runnian(int year);该函数判断某年是否是闰年,参数year表示要判断的年份,返回值1表示该年为闰年,0表示该年为平年。
3.1.2struct tm* getDay();该函数用以取得系统的时间。
该函数没有参数,返回值类型为struct tm*,是一个包含时间的结构体。
3.1.3int jiancha(int year,int month,int day);该函数用以判断输入的年份是否合法,参数为要判断的年月日,返回值为1表示该日期合法,为0表示不合法。
3.1.4int getwDay(int year,int month,int day);该函数用以根据一个日期推断星期,参数为要判断的年月日。
返回值为整型,123456分别表示星期一到星期六,0表示星期天。
3.1.5void chaxun();该函数用以显示要查询的日期的月历,无参数和返回值,。
3.1.6void inline backMenu();该函数为内联函数,用以实现完成某项功能后按任意字符键返回主菜单,无参数和返回值。
3.1.7void caidan(int &year,int &month,int &day);该函数参数为系统日期,无返回值,用户在该函数执行时可以选择功能。
4程序测试4.1进入程序后显示4.2按任意键返回主菜单4.3进入主菜单后,按1,显示当前时间4.4在主菜单界面按2,进行日立的查询,并经时期的合法性判断和平润年的判断。
例如输入:2020 12 20.由于输入合法会显示:4.5进入程序后显示输入:2012 11 40,由于输入不合法,会进行报错,要求重新输4.6在主界面中输入3,程序退出4.7在主界面中输入:eufhg,会显示5.程序原代码:#include<stdio.h>#include<time.h>#include<math.h>#include<string.h>#include<windows.h>#include<conio.h>int year,month,day; //全局变量记录时间intdaysOfMonth[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,3 0,31,30,31,31,30,31, 30,31}};int runnian(int year) //判断是否是闰年{ return(year%4==0&&year%100!=0||year%400==0)?1:0;}struct tm* getDay()//从系统取得当前时间{time_t timer;struct tm* gmt;time(&timer);gmt=localtime(&timer);return gmt;}int jianca(int year,int month,int day)//检查日期是否正确{if(year<0||month<1||month>12||day<1||day>31)return 0;switch(month){case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(day>31)return 0;break;case 4:case 6:case 9:case 11:if(day>30)return 0;break;default:if(runnian(year)&&day>29)return 0;else if(runnian(year)==0&&day>28)return 0;}return 1;}int getwDay(int year,int month,int day)//取得星期{int nday=0,nDay,i,w;for(i=0;i<month-1;i++)nday+=daysOfMonth[runnian(year)][i];nday+=day;nDay=year-1+(year-1)/4-(year-1)/100+(year-1)/400+nday;w=nDay%7;return w;}int week(int year,int month,int day)//取得星期{int nday=0,nDay,i,w;for(i=0;i<month-1;i++)nday+=daysOfMonth[runnian(year)][i];nday+=day;nDay=year-1+(year-1)/4-(year-1)/100+(year-1)/400+nday;w=nDay%7;return w;}void ty(int year,int month,int day)//打印月历{int i;char wday[7][4]={"日","一","二","三","四","五","六"};printf("####################################\n");printf("####################################\n");printf("###### %d年%d月%d日 #######\n",year,month,day); printf("************************************\n");printf("************************************\n");for(i=0;i<7;i++)printf("%5s",wday[i]);printf("\n");int w;int nowDay=1;w=week(year,month,nowDay);//找到第一天的星期int n;n=daysOfMonth[runnian(year)][month-1];{ //放置第一天if(w==0)printf("%5d",nowDay);else if(w==1)printf("%10d",nowDay);else if(w==2)printf("%15d",nowDay);else if(w==3)printf("%20d",nowDay);else if(w==4)printf("%25d",nowDay);else if(w==5)printf("%30d",nowDay);elseprintf("%35d\n",nowDay);}nowDay++;for(i=1;i<n;i++){w=week(year,month,nowDay);printf("%5d",nowDay);if(w==6) //如果是星期六则换行打印puts("\n");nowDay++;}printf("\n************************************\n");printf("************************************\n");}void caxun()//查询日历{system("cls");int year,month,day;printf("请输入你要查询的日期(格式为年月日,如2009 11 3):");scanf("%d%d%d",&year,&month,&day);while(!jianca(year,month,day)) //如果日期输入不正确,则重新输入{printf("%c你输入的日期错误,请重新输入:");scanf("%d%d%d",&year,&month,&day);}system("cls");if(runnian(year))printf("\n 闰年\n\n");else printf("\n 平年\n\n");ty(year,month,day);}void inline backMenu(){printf("请按任意字符键进入主菜单:\n");getch();/*system("cls");*/}void caidan(int &year,int &month,int &day)//主菜单{ system("cls");printf("---------------------------------------------------\n");printf("---------------------------------------------------\n"); printf("---------------------------------------------------\n");printf("---------------------------------------------------\n");printf("***************************************************\n");printf("***************************************************\n");printf("*********** 主菜单 *************\n");printf("***************************************************\n");printf("****************************************************\n");printf("*********** 1.显示日历 *************\n");printf("*********** 2.查询日历 *************\n");printf("*********** 3.退出 *************\n");printf("*********** *************\n");printf("*********** *************\n");printf("*********** *************\n"); char m[100];int g=0;do{int f=0;do{f=0;printf("\n请输入相应数字:");scanf("%s",m);if(strlen(m)>2)f=1;}while(f==1);switch(*m){case '1':system("cls");ty(year,month,day);backMenu(); //实现任意键返回主菜单caidan(year,month,day);break;case '2':system("cls");caxun();backMenu();caidan(year,month,day);break;case '3':system("cls");printf("程序已退出!\n");break;default:printf("%c输入错误!\n");g=1;}}while(g);}void main(){struct tm *gmt=getDay();year=gmt->tm_year+1900;month=gmt->tm_mon+1;day=gmt->tm_mday;ty(year,month,day);//用系统时间进行初始化,打印当前月历 backMenu();caidan(year,month,day);}设计体会及改进意见:此程序是自己所写的第一个功能比较完整的能实现一定的实际功能的程序,代码比较短,不到300行,实现的功能有显示当前日历,进行某天的查询,闰年的判断,日期的合法性判断,。