C语言课程设计
一、题目及功能描述
题目:万年历的设计
利用C语言设计出万年历,使其实现如下要求
1、输入一个年份,在屏幕上输出该年的年历(包括每月的天数和所对应的星期几),并且在每月的左上角或右上角打印出相应的年份和月份,要求输出界面尽可能整齐、美观,符合年历显示规范。假定输入的年份在1-9999年之间。
2、输入年月,输出该月的月历。
3、输入年月日,输出距今天还有多少天,是星期几,是否是公历节日。:
4、指定键盘的某些键,用于控制变换不同年、月、日的显示。即:当前若正在显示20##年的年历,按下键盘“←”方向键后,年历变为20##年的。
二、使用的所有变量的说明
变量说明:(以下均为整型变量)
year 表示年份的变量
month 表示月份的变量
day 表示日期的变量
select 表示菜单选择的变量
i 表示月份的变量
j 表示一个月中的某一天的变量
sum 判断某天是一年中的第几天的变量
number判断某天离公元1年1月1日还有几天的变量
a[] 表示每月天数的数组变量
year1 系统时间年份的变量
month1 系统时间月份的变量
day1 系统时间日期的变量
三、程序清单及其说明
#include "time.h" /*包含的头文件*/
#include "stdio.h"
#include "math.h"
#include "windows.h"
#include "conio.h"
#define KEYNUMUp 0x48 /*宏定义*/
#define KEYNUMDown 0x50
#define KEYNUMLeft 0x4b
#define KEYNUMRight 0x4d
#define KEYNUMPageUp 0x49
#define KEYNUMPageDown 0x51
int eachyeartotal(int year,int month,int day); /*函数声明*/
int counterdays(int year,int month,int day);
int nowtime(int year,int month,int day);
int week(int year,int month,int day);
int maxDay(int year,int month);
int isleap(int year);
void whatweek(int year,int month,int day);
void display(int year ,int month);
void display2(int year,int month);
void display3(int year,int month,int day) ;
void setDay1(int year,int month,int day);
void setDay2(int year,int month,int day);
void setDay3(int year,int month,int day);
void jieri(int month,int day);
void display1(int year);
void getmenu();
void main() /*主函数*/
{
int year,month,day,select;
while(1)
{
getmenu();
printf(" 请输入相应数字:"); /*菜单选择 */
scanf("%d",&select);
system("cls");
switch(select)
{
case 1: /*当选择为1时显示年历*/
printf(" 年历显示:输入年(如2011):");
scanf("%d",&year);
if(year>0&&year<10000) /*显示年份从0-10000 */
{
display1(year); /*调用函数*/
printf(" 提示 按↑:上一年 按↓:下一年 按其他键:返回菜单\n\n");
setDay1( year,month, day);
}
else
system("cls");
printf(" 输入无效,重新输入!\n");
break;
case 2: /*当选择为2显示月历*/
printf(" 月历显示:输入年月(如2011,6):");
scanf("%d,%d",&year,&month);
if(year>0&&year<10000&&month>=1&&month<=12)
{
display2(year,month);
printf(" 提示 按←:上个月 按→:下个月 按其他键:返回菜单\n\n");
setDay2( year,month, day);
}
else
system("cls");
printf(" 输入无效,重新输入!\n");
break;
case 3: /*当选择为3时显示日期*/
printf(" 日期显示:输入年月日(比如2011,6,23):");
scanf("%d,%d,%d",&year,&month,&day);
if(year>0&&year<10000&&month>=1&&month<=12&&day>=1&&day<=maxDay(year,month))
{
display3(year,month,day);
printf(" 提示 按PageUp:前一天 按PageDown:后一天 按其他键:返回菜单\n\n");
setDay3( year,month, day);
}
else
system("cls");
printf(" 输入无效,重新输入!\n");
break;
case 4:
exit(0);
default: /*当输入其他数字时,输入无效,重新输入*/
system("cls");
printf(" 输入无效,重新输入!\n");
}
}
}
int isleap(int year) /*判断是否为闰年*/
{
if(year%4==0&&year%100!=0||year%400==0)
return 1;
else
return 0;
}
int maxDay(int year,int month) /*每月的天数*/
{
int a[]={31,28,31,30,31,30,31,31,30,31,30,31}; /*每个月中的天数*/
if(isleap( year))
a[1]=29; /*闰年2月份有29天*/
return a[month-1];
}
int eachyeartotal(int year,int month,int day) /*判断某天是一年中的第几天*/
{
int i,sum=0;
for(i=1;i<month;i++)
sum+=maxDay(year,i);
sum+=day;
return sum;
}
int week(int year,int month,int day) /*对天数进行判断确定是星期几*/
{
int number=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400
+eachyeartotal(year,month,day);
number=number%7 ;
return number;
}
void display(int year ,int month) /*输出年月*/
{
int max,number,i,j=1;
max=maxDay(year,month);
number=week(year,month,1);
printf(" %4s %4s %4s %4s %4s %4s %4s\n","Sun","Mon","Tue","Wed",
"Thu","Fri","sat");
for(i=0;i<number;i++)
printf(" "); /*1号前的星期补空格*/
while(j<=max)
{
printf("%6d",j);
if (i%7==6)
printf("\n"); /* 每7格换一行*/
i++;
j++;
}
printf("\n\n");
}
void display1(int year) /*输出年历*/
{
int i;
printf("\n");
for(i=1;i<=12;i++)
{
printf("%d 年 %d 月\n\n ",year,i);
display(year,i);
}
}
void display2(int year,int month) /*输出月历*/
{
printf("\n%d 年 %d 月\n ",year,month);
display(year,month);
}
void display3(int year,int month,int day) /*输出日历*/
{
whatweek( year,month,day);
jieri(month,day);
counterdays(year,month, day);
}
int counterdays(int year,int month,int day) /*判断今天距特定日期的天数*/
{
int year1, days0,days1,month1,days, day1;
time_t timep;
struct tm *p;
time(&timep);
p=gmtime(&timep);
year1=(1900+p->tm_year) ;
month1=(1+p->tm_mon) ;
day1=(p->tm_mday); /*获取系统时间year1、month1、day1分别为年、月、日*/
days0=(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day);
days1=(year1-1)*365+(year1-1)/4-(year1-1)/100+(year1-1)/400+eachyeartotal(year1,month1,day1);
days=days0-days1; /*计算出两个日期之间的时间差*/
printf("\n 今天距%d年%d月%d日还有%d天\n\n",year,month,day,days);
return days;
}
void whatweek(int year,int month,int day) /*判断是星期几*/
{
int number;
number=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day);
number=number%7 ;
switch( number)
{
case 0:
printf( "\n %d年%d月%d日是星期日",year,month,day);break;
case 1:
printf( "\n %d年%d月%d日是星期一",year,month,day);break;
case 2:
printf( "\n %d年%d月%d日是星期二",year,month,day);break;
case 3:
printf( "\n %d年%d月%d日是星期三",year,month,day);break;
case 4:
printf( "\n %d年%d月%d日是星期四",year,month,day);break;
case 5:
printf( "\n %d年%d月%d日是星期五",year,month,day);break;
case 6:
printf( "\n %d年%d月%d日是星期六",year,month,day);break;
default:
system("cls");
printf(" 出现错误!\n" );
}
}
void jieri(int month,int day) /*判断是否公历节日*/
{
if(month==1)
switch(day)
{
case 1:
printf(",这天是元旦");
}
if(month==2)
switch(day)
{
case 14:
printf(",这天是情人节");
}
if(month==3)
switch(day)
{
case 8:
printf(",这天是妇女节");
break;
case 12:
printf(",这天是植树节");
}
if(month==4)
switch(day)
{
case 1:
printf(",这天是愚人节");
}
if(month==5)
switch(day)
{
case 1:
printf(",这天是劳动节");
break;
case 4:
printf(",这天是青年节");
}
if(month==6)
switch(day)
{
case 1:
printf(",这天是儿童节");
}
if(month==7)
switch(day)
{
case 1:
printf(",这天是建党节");
}
if(month==8)
switch(day)
{
case 1:
printf(",这天是建军节");
}
if(month==9)
switch(day)
{
case 10:
printf(",这天是教师节");
}
if(month==10)
switch(day)
{
case 1:
printf(",这天是国庆节");
}
}
void setDay1(int year,int month,int day) /*通过键盘“↑”“↓”控制年历的变换*/
{ char k;
getch();
k=getch();
switch(k)
{
case KEYNUMUp: /*“↑”年份减小*/
if(year<2)
{
system("cls");
printf(" 警告!超出范围!\n");
break;
}
year--;
display1(year);
setDay1(year,month,day);
break;
case KEYNUMDown: /*“↓”年份变大*/
year++;
display1(year);
setDay1(year,month,day);
break;
default:
system("cls");
}
}
void setDay2(int year,int month,int day) /*通过键盘“←”“→”控制月历的变换*/
{
char k;
getch();
k=getch();
switch(k)
{
case KEYNUMLeft: /*“←”月份变小*/
if(month<2)
{
month+=12;
year--;
}
if(year<1)
{
system("cls");
printf(" 警告!超出范围!\n");
break;
}
month--;
display2(year , month);
setDay2(year,month,day);
break;
case KEYNUMRight:/*“→”月份变小*/
if(month>11)
{
month-=12;
year++;
}
if(year<9999);
month++;
display2(year , month);
setDay2(year,month,day);
break;
default:
system("cls");
;
}
}
void setDay3(int year,int month,int day) /*通过键盘“PageUp”“PageDown”控制日期的变换*/
{
char k;
getch();
k=getch();
switch(k)
{
case KEYNUMPageUp: /*“PageUp”日期变小*/
if(day<2)
{
month--;
day=maxDay(year,month);
}
if(month<1)
{
month+=12;
year--;
}
if(year<1)
{
system("cls");
printf(" 警告!超出范围!\n");
break;
}
day--;
display3(year , month,day);
setDay3(year,month,day);
break;
case KEYNUMPageDown: /*“PageDown”日期变大*/
day++;
if(day>maxDay(year,month))
{
day=1;
month++;
}
if(month>12)
{
month-=12;
year++;
}
if(year<10000);
display3(year , month,day);
setDay3(year,month,day);
break;
default:
system("cls");
;
}
}
void getmenu() /* 显示菜单选择*/
{
printf(" ************主菜单************\n\n");
printf(" * 欢迎进入万年历系统 *\n\n");
printf(" * 1、年历显示 *\n\n");
printf(" * 2、月历查询 *\n\n");
printf(" * 3、日期查询 *\n\n");
printf(" * 4、退出系统 *\n\n");
printf(" ******************************\n\n");
}
四、运行结果清单
打开软件,进入如下菜单界面,输入数字进行选择
1年历的显示
(1)输入数字1进入年历的显示
(2)输入年份2011,显示20##年的年历如下
(3)按↑键盘显示上一年(20##年)的年历,显示如下
(4)按↓键盘显示上一年(20##年)的年历,显示如下
2、月历的显示
(1)在菜单中选择2,进入月历的显示,输入2011,6,显示20##年6月份的月历,显示效果如下
(2)按←键盘显示上一个月(5月)的月历,显示效果如下
(3)按→键盘显示上上个月(7月)的月历,显示效果如下
3、日历的显示
(1)输入选择3进入日历的显示,如图输入2011,10,1显示这天的星期,是否为公历节日,距离现在还有多少天
(2)按PagDown显示前一天的日历,显示如下
(3)按PagUp显示后一天的日历,显示如下
4 退出程序
输入选择4,显示如下界面,按任意键退出程序
五、总结和体会。
本次用C语言编写的万年历系统主要实现了年历、月历、日历的显示,并且可通过键盘来变换相应的年月日,最终的设计结果达到的这些要求,是一次成功的课程设计。
在设计初期,首先温习了课本内容,再次熟熟悉了C程序,然后广泛的查找有关万年历的资料,并结合查找到的资料,整理出设计的主要思路,画出流程图,最终写出了源程序,并编译成功,在实验中,碰到了不少问题,其中包括如何获取系统时间,如何计算任意时间的时间差,这些困难,都通过查阅资料和问同学得到了解决。当然,由于时间和能力的原因,选作部分农历的显示没有实现。
通过这次课程设计,使我对C语言了解不在停留在书面的了解,而是有了更深的理解,培养了自己的分析能力和设计能力,受益匪浅。
附:参考文件
[1] 谭浩强. C程序设计(第三版).北京:清华大学出版社.2005
[2] 谭浩强. C程序设计题解与上机指导(第三版).北京:清华大学出版社.2005
[3] 徐慧 林锐 C语言实例解析精粹 .武汉:华中理工大学出版社.1996
[4] 戴建鹏译 C语言大全(第三版) .北京:电子工业大学出版社.1994