1. 功能说明
功能一:日历显示
说明:
1)在当前的终端窗口中显示当前的年、月、日。例如,当前日期为2017年7月20日;
2)表格的标题是年月;
3)表头是星期,并且是从星期日开始;
4)显示日期时,如果当前月份的1日不是星期日,则用上个月的末尾几日补齐表格。同样,如果当前月的结尾日期不是周六,则用下个月的开始几日补齐;
5)普通的日期用白色显示,当前日期用绿色显示,星期六和星期日用红色显示,用来补齐表格的日期用灰色显示。
功能二:键盘控制
说明:
1)用户使用键盘的左、右键控制月份的增减,上、下键控制年份的增减;
2)用户想直接查看某日期的日历时,可以按下“F”键,提示用户输入年、月,在用户输入结束以后,显示用户输入的日期日历。如图,按下“F”键后,输入2015/12并按下Enter键,程序切换到2015年12月的日历显示;
3)按下“ESC”键,退出整个程序。
2. 知识点
1)一维数组、二维数组
2)逻辑结构
顺序结构、循环结构、分支结构
3)Zeller公式
蔡勒(Zeller)公式 计算历史上的某一天是星期几?未来的某一天是星期几?
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
公式中的符号含义如下,
w:星期;
c:世纪-1;
y:年(两位数);
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年 的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算);
d:日;
[ ]代表取整,即只要整数部分。
(C是世纪数减一,y是年份后两位,M是月份,d是日数。1月和2月要按上一年的
13月和 14月来算,这时C和y均按上一年取值。)
算出来的W除以7,余数是几就是星期几。如果余数是0,则为星期日。
以2049年10月1日(100周年国庆)为例,用蔡勒(Zeller)公式进行计算,过程如下:
蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1
=49+[12.25]+5-40+[28.6]
=49+12+5-40+28
=54 (除以7余5)
即2049年10月1日(100周年国庆)是星期5。
但是计算2000年3月1日:
蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=0+[0/4]+[20/4]-2×20+[26×(3+1)/10]+1-1
=0+[0]+5-40+[10.4] +1-1
=0+0+5-40+10
=-25
那么-25 % 7 = -4与实际不匹配,为了修正w值 ,故将w 的值加上42,使之为正值,(w+42)%7 = w%7 + 42%7,如果w为正值,(w+42)%7 = w%7,结果不变。
4)Curses库
HTTP://tldp.org/HOWTO/NCURSES-Programming-HOWTO/index.html
5)time.h库中相关函数,用于获取当前时间。
3. 设计思路
a.日历显示部分:
定义一个6行7列的二维数组存放要显示的日期。先判断要显示月份的1日在星期几。如果在星期日(如表2),则分三个部分:
①为了使本月的日期居中,第一行存放上个月末的日期;
②第二行开始存放本月的日期直到本月的日期全部存完;
③接着存放下个月初的日期直到整个数组存满。
如果在星期日(如表3),则分四个部分:
①第一行中本月1日前存放上个月末的日期;
②第一行的1日以及1日后存放本月的日期;
③接着存放本月的日期直到本月的日期全部存完;
④最后存放下个月初的日期直到整个数组存满。
最后,把数组的值在指定位置打印出来,普通的日期用白色显示,当前日期用绿色 显示,星期六和星期日用红色显示,用来补齐表格的日期用灰色显示。
b.键盘控制部分:
通过getch() 获取从键盘输入的键值,运用switch语句,实现各个按键的功能。
c.系统流程图
4. 源码分析
/*********************************************************
* Author : 谢保成
* File Name : calendar.c
* Date : 2017/7/15
* H/W Platform : ubuntu 16.04
* Description : Define global variables and functions
*********************************************************/
#include "calendar.h"
//主函数
int main(int argc, const char *argv[])
{
int temp1, temp2;
//初始化
initscr(); /* Start curses mode */
start_color();
/* COLOR_BLACK 0
COLOR_RED 1
COLOR_GREEN 2
COLOR_YELLOW 3
COLOR_BLUE 4
COLOR_MAGENTA 5
COLOR_CYAN 6
COLOR_WHITE 7 */
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
init_pair(6, COLOR_CYAN, COLOR_BLACK);
init_pair(7, COLOR_WHITE, COLOR_B