简单桌面日历

问题描述:设计一个C语言程序,实现桌面日历的功能,要求:

  1. 按照输入的年份,显示这一年每月日历;

2、按照输入的年份和月份,显示这个月的日历;

3、显示当月的日历,日历显示形式同挂历。

解决思路:设计几个函数,分别用于实现判断是否为闰年、该月有多少天,该月第一天是星期几、遍历等等,在主函数里用switch语句实现不同功能,在while语句里循环。

功能模块图

代码

#include <stdio.h>
#include <time.h>
// 判断是否为闰年函数
int isLeapYear(int);
// 判断某年某月的第一天是周几的函数
int daysWeek(int, int);
// 判断月份有几天函数
int monthDays(int, int);
// 输出某年某月日历函数
void monthCalendar(int, int);
int main() {
	int Year, Month,day;
	// 模式选择,ll
	int mode;
	while(1) {
		Year=0,Month=0,mode=0;
		printf("-----------------------------------------\n");
		printf("|            简易桌面日历               |\n");
		printf("-----------------------------------------\n");
		printf("|     (1) 输入年份打印出全年历          |\n");
		printf("-----------------------------------------\n");
		printf("|     (2) 输入年份月份打印出月日历      |\n");
		printf("-----------------------------------------\n");
		printf("|     (3) 打印出当前月的日历            |\n");
		printf("-----------------------------------------\n");
		printf("|     (4) 退出程序                      |\n");
		printf("-----------------------------------------\n");
		printf("|   请输入数字1 2 3 4以选择要使用的功能 |\n");
		printf("-----------------------------------------\n");
		printf("输入数字:");
		scanf("%d", &mode);
		rewind(stdin);
		printf("\n");
		switch(mode) {
			case 1:
				// 实现第一个功能
				printf("请输入年份: ");
				scanf("%d", &Year);
				rewind(stdin);
				if(Year<1900){
				printf("\n无法查询1900年前的日历,输入无效!\n"); 
				printf("\n");
				}else{
				// 从1遍历到12月 代表1月到十二月
				for (int i = 1; i <= 12; i++) {
					printf("--------------------------------------------------\n");
					printf("%d 年 %d 月\n", Year, i);
					monthCalendar(Year, i);
				}
			}
				break;
			case 2:
				printf("请输入年份: ");
				scanf("%d", &Year);
				rewind(stdin);
				printf("请输入月份: ");
				scanf("%d", &Month);
				rewind(stdin);
				//判断输入的月份是否符合常理
				if(Month>12||Month<1||Year<1900) {
					printf("\n无此月份或无法查询1900年前的日历,输入无效!\n");
					printf("\n");
				} else{
					printf("%d 年 %d 月\n", Year, Month);
					monthCalendar(Year, Month);
				}
				break;
			case 3:
				// 固定格式
				time_t timep;
				struct tm *p;
				time(&timep);
				p = gmtime(&timep);
				Year = 1900 + p->tm_year;
				Month = 1 + p->tm_mon;
				day=p->tm_mday; 
				printf("当前时间为:%d年%d月%d日\n", Year, Month,day);
				printf("--------------------------------------------------\n");
				printf("%d 年 %d 月\n", Year, Month);
				monthCalendar(Year, Month);
				break;
			case 4:
				printf("退出成功!");
				return 0;
			default:
				printf("请输入数字1 2 3 4选择功能 输入其他字符无效!\n\n");
		}
	}
}
// 判断是否为闰年
int isLeapYear(int Year) {
	// 如果能整除4且不能整除100或能整除400,则为闰年
	return	(Year % 4 == 0 && Year % 100 != 0) || Year % 400 == 0;
}
// 判断月份有几天
int monthDays(int Year, int Month) {
	if (Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12) {
		return 31;
	} else if (Month == 4 || Month == 6 || Month == 9 || Month == 11) {
		return 30;
	} else {
		if (isLeapYear(Year)) {
			return 29;
		}
		// 如果不是闰年 天数为28天
		return 28;
	}
}
// 判断某年某月的第一天是周几
int daysWeek(int Year, int Month) {
	// day用于记录总天数
	// day1记录每月的天数,结合下面代码理解
	int day = 0, day1 = 0;
	// 得到从1900年到某年的天数
	for (int i = 1900; i < Year; i++) {
		// 判断闰年
		if (isLeapYear(i)) {
			day = day + 366;
		} else {
			day = day + 365;
		}
	}
	//获得1900年到该月份的天数
	for (int m = 1; m < Month; m++) {
		day1 = monthDays(Year, m);
		// 计算天数
		day =day+ day1;

	}
	// week为某年某月第一天的周几m
	int week = day % 7;
	return week;
}
// 具体实现打印某年某月日历
void monthCalendar(int Year, int Month) {
	printf("--------------------------------------------------\n");
	printf("一\t二\t三\t四\t五\t六\t日\n");
	//判断这个月的第一天是星期几
	int t = daysWeek(Year, Month);
	// 判断月份有几天
	int day1 = monthDays(Year, Month);
	for (int i = 0; i < t; i++) {
		printf("\t");
	}
	//控制输出格式
	for (int i = 1; i <= day1; i++) {
		printf("%d\t", i);
		if ((i + t) % 7 == 0) {
			printf("\n");
		}
	}
	printf("\n");
	printf("--------------------------------------------------\n");
	printf("\n");
}

 遇到的问题:

        scanf("%d", &mode);scanf要去输入一个整形的数赋值给变量mode,但如果你输入一个非法字符,就会出错,mode不会被赋值,还是上一个的值。解决方案是给mode在scanf赋值之前一个不影响程序的值,或将变量mode声明成char类型。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余厌厌厌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值