课程 程序设计基础 题目
用 C语言设计一个年历系统
1 问题要求及任务描述
1.1 题目要求
用 C 语言设计一个年历系统
1.2 主要任务
年历系统首先对于输入的任一年, 能够给出该年每月的日期及实际周几的对应情况, 与实际的星期数垂直对齐,如下表所示(当输入 2004 时显示如下) :
Input the year:2004
The calendar of the year 2004. Januray 1 February 2
n on Tue u Su M Wed Th Fr i Sat Sun Mon Tue Wed Thu Fri Sat
1 2 3 1 2 3 4 5 6 7
4 5 6 7 8 9 10 8 9 10 11 12 13 14 11 12 13 14 15 16 17 15 16 17 18 19 20 21 18 19 20 21 22 23 24 22 23 24 25 26 27 28
25 26 27 28 29 30 31
29
Mar ch
3
A
pri
l 4
Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 1 2 3
7 8 9 10 11 12 13 4 5 6 7 8 9 10
14 15 16 17 18 19 20 11 12 13 14 15 16 17
1 / 11
21 22 23 24 25 26 27 18 19 20 21 22 23 24 28 29 30 31 25 26 27 28 29 30
功能要求 :
⑴ 输入任一年将显示出该年的所有月份日期, 对应的星期, 输出的格式如上表要求 (注 意闰年情况) ;
⑵ 输入任意日期(包括年、月、日,格式有 yyy/mm/dd 、 dd/mm/yyyy 、 mm/dd/yyyy 、 和 yyyy,mm,dd 、 mm,dd,yyyy 、 dd,mm,yyyy 六种基本情况) ,要求能够显示出该日期是本年 的哪一周,是星期几。
2 解决问题的主要思路和方法
2.1 关键问题
1、输入任一年将显示出该年的所有月份日期,对应的星期,但是要并排月份,还要注意闰 年情
况。
2、一个月份中开始和最后对应的星期可能是上个月或下个月的天数,但是要空出来。 3、输入任意日期,然后要显示出该日期是本年的哪一周,星期几。
2.2 拟采用解决问题的方法
1、先判断输入的年份是否是闰年。
2、用基姆拉尔森计算公式去计算某年第一天是星期几。
3、月份的日子可以用 for 语句去实现,特别的,一个月份中开始和最后对应的星期可能是 上个
月或下个月的天数,因此要用 for 语句去腾空。
4、根据输入的日期和基姆拉尔森公式的变换得出能计算出该日期是本年的哪一周,是星期 几的
公式。
5、熟悉运用一些没学过的函数,如 strcat , sprintf , strlen 函数。
2.3 主要算法和处理流程图
2 / 11
int judge( int
year, int month )
month==1 或 month
==3
或 month == 5 或 month==7 或 month==8 或 month==10 或
month ==12 ?
返回( 1)
2)
3 / 11
month == 2 ?4)Y
year % 4
!= 0 或 year % 100 == 0 且 year % 400不等于
0?
void cal
N
定义整型 yea 定义常量字符数组 mon
定义字符数组 temp
3)
输入所求年
a =(year+(year-1
100+(year-1)/
i < 12 ?
Y memset( temp
输出月份名, 和星期
AGAIN: line
n = judge( year, i
输出
m = 1 m < 32?
输出 m 的数
Y
strcat( tempOu
返回(返回
(
Y
sum+1;
3 程序实现
3.1 程序实现时应考虑的问题
3.2 主要源代码及说明
int judge( int year, int month ) //
{
定义 judge 函数
5 / 11
if( month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12 ) return( 1 );// 返回 1 时,表示天数为 31 天的月份 else if( month == 2 )
{
if( year % 4 != 0 || year % 100 == 0 && year % 400 != 0 ) // 年,真
为平年 return( 2 ); else
return( 3 );
}
else return( 4 );
}
void calendar()
{
int year, i, j, a, n, m, k, line; // 定义变量
const char month[ 12 ][ 12 ] = { \"January 1\
\"April 4\
判断闰
定义一个三维数组 tempOut[ 左 char tempOut[ 2 ][ 6 ][ 40 ], temp[ 10 ];//
0 右 1][ 每月第几行 ][ 每行字符明细 ] 。 printf( \"please inter the year:\" ); // 输入所求年
份 scanf( \"%d\
printf( \"\\n\" );
printf( \"the calendar of the year%d.\\n\
判断每年的第一天是
a =(year+(year-1)/4-(year-1)/100+(year-1)/400)%7; //
周几 当 a 值为 0 的时候,对应周日
for( i = 0; i < 12; i += 1 )// 月份循环
{
memset( tempOut, 0, sizeof( tempOut ) );//memset
一段内存块中填充某个给定的值 , 它是对数组进行清零操作
printf( \"%-33s%s\\n\是先
左对齐再留 33 个空格
printf( \"==============================
====================\\n\" );
printf( \" Sun Mon Tue Wed Thu Fri Sat Sun
Sat\\n\" );
\"November 11\
函数的作用是在
输出月份名 ,-33
Mon Tue Wed Thu Fri
AGAIN:
6 / 11
line = 0;
n = judge( year, i + 1 ); //
调用函数, n 值为 1234 ,代表每月为多
代表每年第一天,后为每月前空格
少天
for( k = 0; k < a; k ++ ) // a
天数
strcat( tempOut[ i % 2 ][ 0 ],
4 个空格接到 tempout[i%2][0]
for( m = 1; m < 32; m++ )//
{
\" );// 运用 strcat 函数把
每月天数循环
sprintf( temp, \"%4d\
输出格式占 4 列,右端对齐 运用
strcat 函数 有足够的空间存放 temp 的 strcat( tempOut[ i % 2 ][ line ], temp );//
内容 把 temp 数组拷贝到 tempout 所指的末尾,且 tempout
if( ( a + m ) % 7 == 0 )
line ++;
if( n == 1 && m == 31 ) break; //
从此处至以下执行整月停
else if( n == 2 && m == 28 ) break; 止
else if( n == 3 && m == 29 ) break;
else if( n == 4 && m == 30 ) break;
}
a = ( a + m ) % 7; // a 为每月末行天数
if( i % 2 == 0 ) {
i ++; goto AGAIN; }
else for( j = 0; j < 6; j ++ )
{
if( strlen( tempOut[ 0 ][ j ] ) == 0 && strlen( tempOut[ 1 ][ j ] ) == 0 ) break;// 运用
strlen 函数判断检查左右列是否都没有第六行,如果是就可以省去 空行的输出了。
printf( \"%-33s%s\\n\}
printf( \"==============================
==============================\\n\\n\" );// 输出左边的字符串,长度 33 ,使得右边字串 对
齐。
void find_day()
{
int a,day,month,year,sum,leap,S,k,W;// 定义变量 printf(\"\\n 请输入年月日 (格式如 2004
7 / 11
11 1):\\n\"); scanf(\"%d%*c%d%*c%d\switch(month)
{
case 1:sum=0;break; case 2:sum=31;break; case 3:sum=59;break; case 4:sum=90;break; case 5:sum=120;break; case 6:sum=151;break; case 7:sum=181;break; case 8:sum=212;break; case 9:sum=243;break; case 10:sum=273;break; case 11:sum=304;break; case 12:sum=334;break; default:printf(\"data error\");break;
}
sum=sum+day;
if(year%400==0||(year%4==0&&year%100!=0))// 判断闰年还是平年 leap=1; else leap=0;
if(leap==1&&month>2) sum++;
S=(year-1+(year-1)/4-(year-1)/100+(year-1)/400+sum)%7;//S/7 的系数就是 星期数 a=(year+(year-1)/4-(year-1)/100+(year-1)/400)%7;
k=(sum+a)%7;// 判断 k 能否被 7 整除,是否有余数,有余数则周数 +1 if(k==0)
{
W=(sum+a)/7;//W 代表第几周,特别的是从星期日到星期一,而不是从星期 一到星期日 printf(\"
}
第 %d周 \
else
8 / 11
{
W=(sum+a)/7; W=W+1;
printf(\" 第%d周 \
switch(S)
{
case 1:printf(\" case 2:printf(\" case 3:printf(\" case 4:printf(\" case 5:printf(\" case 6:printf(\" case 0:printf(\"
}
printf(\"\\n\");
}
4.1 测试结果及分析
星期一 \\n\");break; 星期二 \\n\");break; 星期三 \\n\");break; 星期四 \\n\");break; 星期五 \\n\");break; 星期六 \\n\");break; 星期日 \\n\");break;
4 测试9 / 11
10 / 11
5 小结
5.1 本问题解决方法及程序实现小结
1用基姆拉尔森计算公式去计算某年第一天是星期几
、
a=(year+(year-1)/4-(year-1)/100+(year-1)/400)%7;// 在公式中 year 表示年数 , 公
式由百度搜索得出
2
为了并排月份,定义了一个三维数组 char tempOut[ 2 ][ 6 ][ 40 ], temp[ 10 ];// 、 tempOut[ 左 0 右 1][ 每月第几行 ][ 每行字符明细 ] 。
3、运用 memset、strcat 、sprintf 函数:memset( tempOut, 0, sizeof( tempOut ) );//memset 函数
的作用是在一段内存块中填充某个给定的值 , 它是对数组进行清零操作。
strcat( tempOut[ i % 2 ][ 0 ], \" \" );// 运用 strcat 函数把 4 个空格接到
tempout[i%2][0] 。
sprintf( temp, \"%4d\输出格式占 4 列,右端对齐,特别注意, sprintf 针
对的是把一些内容放进字符数组,用法与 printf 有点相似。
5.2
尚未解决的问题及下一步工作思路 本程序还是有缺点,当要选择数
字时,若输入了字母等非数字类型,然后程序就不能 运行。还有 goto 语句使用太多,虽然
goto 语句很好用,但是却不太好。
6 参考文献
[1] 苏小红 .C 语言大学实用教程 ( 第三版 ). 电子工业出版社 .2012.5 [2]
11 / 11
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- net188.cn 版权所有 湘ICP备2022005869号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务