Demo entry 6363186

Calendar Program with Language C

   

Submitted by Albert Summer on May 12, 2017 at 14:00
Language: C. Code size: 6.7 kB.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#define KEYESC 27	//“Esc”键
#define KEYENTER 13	//“Enter”键
#define KEYPLUS 43	//“+”键
#define KEYMINUS 45	//“-”键
#define KEYSTAR 42	//“*”键
#define KEYSLASH 47	//“/”键
//宏定义键盘键值
const int isLeap(int year); 	//判断平闰年,闰年返回1,平年返回0
const int getMonthDays(int year,int month); 	//获取year年month月的天数并返回
const int yearDays(int year); 	//获取year年的天数并返回
const int isWeek(int year,int month,int day); 	//判断year年month月day日为星期几并返回对应数字
void reset_date();	//重置为当前年月
void printCalendar(int year,int month); 	//输出日历
int calendar_input();	//数字输入模式
int calendar_control();	//符号控制模式
//函数声明

int year,month; 	//全局变量“年”,“月”
int main(){
	int action=0;
	system("cls");	//Windows命令行清屏,下同
	reset_date();
	while(1){
		system("title C语言万年历小程序");	//Windows命令行更改窗口标题
		printf("\n欢迎使用万年历!\n\n当前日期是:");
		system("date /t");	//Windows命令行显示当前日期
		printf("\n");
		printCalendar(year,month);
		printf("\n\n请使用数字键盘操作。\n数字输入模式 - 直接按数字键进入,手动输入年月查询对应日历。\n符号控制模式 - 按\“*\”\“/\”\“-\”\“+\”或\“Enter\”键更改年月查询日历。\n按\“Esc\”键退出。\n");
		action=getch();	//获取下一个按键的键值并赋给action,下同
		system("cls");
		switch(action){ 	//根据获得的键值执行下一步的操作
		case 48:
		case 49:
		case 50:
		case 51:
		case 52:
		case 53:
		case 54:
		case 55:
		case 56:
		case 57:
		//48~57一一对应数字0~9,下同
			calendar_input();
			break;
		case KEYSTAR:
			year++;
			if(year>9999){
				year=9999;
				month=12;
			}	//限制最大年月为9999年12月,下同
			calendar_control();
			break;
		case KEYSLASH:
			year--;
			if(year<1){
				year=1;
				month=1;
			}	//限制最小年月为1年1月,下同
			calendar_control();
			break;
		case KEYMINUS:
			month--;
			if(month<1){
				month = 12;
				year--;
			}
			if(year<1){
				year=1;
				month=1;
			}
			calendar_control();
			break;
		case KEYPLUS:
			month++;
			if(month>12){
				month=1;
				year++;
			}
			if(year>9999){
				year=9999;
				month=12;
			}
			calendar_control();
			break;
		case KEYENTER:
			reset_date();
			calendar_control();
			break;
		case KEYESC:
			exit(0);	//退出程序
			break;
		default:
			continue; 	//按其他键无反应
		}
	}
	return 0;
}

int calendar_input(){
	int action=0,i=0;
	char years[5],months[3]; 	//定义字符数组
	while(1){
		action=0;
		system("cls");
		printf("\n欢迎使用万年历! - 数字输入模式\n\n请以\“YYYYMM\”格式输入年月:");
		for(i=0;i<=3;i++){
			action=getche();	//获得下一个按键键值赋给action并输出键对应字符
			if(action>=48&&action<=57)
				years[i]=action; 	//将键入的数字按顺序送入字符数组,下同
			else if(action=KEYESC){
				return main();
				break;
			}
			else{
				year=-1;
				break;
			}	//禁止非法字符输入,下同
		}
		if(year==-1)
			continue; 	//禁止超范围的年月输入,下同
		else
			year=atoi(years); 	//stdlib.h中的函数
		for(i=0;i<=1;i++){
			action=getche();
			if(action>=48&&action<=57)
				months[i]=action;
			else if(action=KEYESC){
				return main();
				break;
			}
			else{
				month=-1;
				break;
			}
		}
		if(month==-1)
			continue;
		else
			month=atoi(months);
		if(month>12||month<1)
			continue;
		printf("\n\n");
		printCalendar(year,month);
		printf("\n\n请使用数字键盘操作。\n按数字键盘符号键(更改年月)或\“Enter\”键(返回当前)切换为符号控制模式。\n按任意非功能键重新输入。\n按\“Esc\”键返回上一级。\n");
		action=getch();
		system("cls");
		switch(action){
		case KEYESC:
			return main();
			break;
		case KEYSTAR:
			year++;
			if(year>9999){
				year=9999;
				month=12;
			}
			calendar_control();
			break;
		case KEYSLASH:
			year--;
			if(year<1){
				year=1;
				month=1;
			}
			calendar_control();
			break;
		case KEYMINUS:
			month--;
			if(month<1){
				month=12;
				year--;
			}
			if(year<1){
				year=1;
				month=1;
			}
			calendar_control();
			break;
		case KEYPLUS:
			month++;
			if(month>12){
				month=1;
				year++;
			}
			if(year>9999){
				year=9999;
				month=12;
			}
			calendar_control();
			break;
		case KEYENTER:
			reset_date();
			calendar_control();
			break;
		case 48:
		case 49:
		case 50:
		case 51:
		case 52:
		case 53:
		case 54:
		case 55:
		case 56:
		case 57:
			continue;
		default:
			break;
		}
	}
	return 0;
}

int calendar_control()
{
	int action=0;
	while(1){
		printf("\n欢迎使用万年历! - 符号控制模式\n\n            -[/(%4d 年)*  %2d 月]+            \n\n",year,month);
		printCalendar(year,month);
		printf("\n\n请使用数字键盘操作。\n按\“Enter\”键返回当前月份。\n按任意数字键切换为数字输入模式。\n按\“Esc\”键返回上一级。\n");
		action=getch();
		system("cls");
		switch(action){
		case KEYSTAR:
			year++;
			if(year>9999){
				year=9999;
				month=12;
			}
			break;
		case KEYSLASH:
			year--;
			if(year<1){
				year=1;
				month=1;
			}
			break;
		case KEYMINUS:
			month--;
			if(month<1){
				month=12;
				year--;
			}
			if(year<1){
				year=1;
				month=1;
			}
			break;
		case KEYPLUS:
			month++;
			if(month>12){
				month=1;
				year++;
			}
			if(year>9999){
				year=9999;
				month=12;
			}
			break;
		case KEYENTER:
			reset_date();
			break;
		case 48:
		case 49:
		case 50:
		case 51:
		case 52:
		case 53:
		case 54:
		case 55:
		case 56:
		case 57:
			return calendar_input();
			break;
		case KEYESC:
			return main();
			break;
		default:
			continue;
		}
	}
	return 0;
}
//上述函数中的大段switch基本是一样的,但在各个函数下因功能的不同又有所不同,所以并未采取再定义新函数的做法。

void reset_date(){	//此函数借鉴了网络
	time_t timep;
	struct tm *p;
	time(&timep);
	p = localtime(&timep);
	year = p->tm_year+1900;
	month = p->tm_mon+1;
}

const int isLeap(int year){
	if(year%4==0&&year%100!=0||year%400==0){
		return 1;
	}
	else{
		return 0;
	}
}

const int getMonthDays(int year,int month){
	switch(month){
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		return 31;
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		return 30;
		break;
	case 2:
		if(isLeap(year)){
			return 29;
		}else{
			return 28;
		}
		break;
	default:
		return 0;
		break;
	}
}

const int yearDays(int year){ 
	if(isLeap(year)){
		return 366;
	}else{
		return 365;
	}
}

const int isWeek(int year,int month,int day){
	int days=0;
	int i;
	for(i=1;i<year;i++){
		days=days+yearDays(i);
	}
	for(i=1;i<month;i++){
		days=days+getMonthDays(year,i);
	}
	days=days+day;
	return days%7;
}

void printCalendar(int year,int month){
	const char *week[]
	= {"日","一","二","三","四","五","六"};
	int i,row=0;
	for(i=0;i<7;i++){
		printf("%s\t",week[i]); 	//输出日历首行的星期文字
	}
	printf("\n\n");
	for(i=0;i<isWeek(year,month,1);i++){
		printf("\t");	//每个月首日左边的空位置用制表符占位
	}
	for(i=0;i<getMonthDays(year,month);i++){
		printf("%2d\t",i+1); 	//按日历格式输出日期
		if(isWeek(year,month,i+1)==6){
			row ++;
			printf("\n\n");
		}	//逢星期六换行
	}
	if(row<5)
		printf("\n\n");	//保持日历下端文字位置不变
	printf("\n");
}

This snippet took 0.02 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).