C语言入门练手之万年历的实现

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
	//容错处理
	if (argc < 2)
	{
		perror("请输入时间:");
		exit(-1);
	}

	//存储当前时间
	unsigned int year = 0;
	unsigned int mouth = 0;
	unsigned int day = 0;
	
	//存储时间差值
	int dm;
	int dy;
	int dd;
	int m2;

	//分解时间字符串操作
	int i = -1;
	int d = 0;
	while (argv[1][++i])
	{
		if (argv[1][i] == '/' || argv[1][i] == '.')
		{
			d++;
			continue;
		}
		else if (d == 0)
		{
			year = year * 10 + (argv[1][i] - '0');
		}
		else if (d == 1)
		{
			mouth = mouth * 10 + (argv[1][i] - '0');
		}
		else if (d == 2)
		{
			day = day * 10 + (argv[1][i] - '0');
		}
	}

loop:

	if (mouth > 12)
	{
		year++;
		mouth = mouth % 12;
	}
	if (mouth < 1)
	{
		year--;
		mouth = 12;
	}
/*
	if (mouth == 1 || mouth == 3 || mouth = 5 || 
			mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12)
	{
		if (day > 31)
		{
			puts("您输入的月份有问题,已自动转化到月份");
		}
	}
*/

	//以下所有的时间点都是按照同年1月1日算起
	//所以即使同年是闰年也暂时不算闰年
	//所以先把时间减一再与标准时间计算
	//而第一次4年间也存在一次闰年,所以加一
	//计算闰年个数
	if (year == 2000)
	{
		dy = 0;
	}
	else if (year > 2000)
	{
		dy = (year - 2001) / 4 - (year - 2001) / 100 +
			(year - 2001) / 400 + 1;
	}
	else
	{
		dy = (2000 - year) / 4 - (2000 - year) / 100 +
			(2000 - year) / 400;
	}

	//不算闰年一年365天,所以每年都会把星期往后推一天
	//所以实际往后推的时间是 年数 加 闰年数
	dy = (year - 2000) + dy;

	//计算同年本身是否是闰年
	//然后在计算月份的时候补上同年因闰年引起的时间差
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		m2 = 1;
	}
	else
	{
		m2 = 0;
	}

	//计算月份引起的星期差,时间点在每月1号,所以时间差只计算到上个月
	switch (mouth)
	{
		case 1:
			dm = 0;
			dd = 31;
			break;
		case 2:
			dm = 3;
			dd = 28 + m2;
			break;
		case 3:
			dm = 3 + m2;
			dd = 31;
			break;
		case 4:
			dm = 6 + m2;
			dd = 30;
			break;
		case 5:
			dm = 1 + m2;
			dd = 31;
			break;
		case 6:
			dm = 4 + m2;
			dd = 30;
			break;
		case 7:
			dm = 6 + m2; 
			dd = 31;
			break;
		case 8:
			dm = 2 + m2;
			dd = 31;
			break;
		case 9:
			dm = 5 + m2;
			dd = 30;
			break;
		case 10:
			dm = 0 + m2;
			dd = 31;
			break;
		case 11:
			dm = 3 + m2;
			dd = 30;
			break;
		case 12:
			dm = 5 + m2;
			dd = 31;
			break;
		default:
			break;
	}
	
	//所有引起的时间差之和加上标准时间所附带的时间差
	//然后对星期取余,得到当月一号的星期数
	dy = (dy + dm + 6) % 7;
	
	printf("\n您输入的时间是:%d年%d月%d日,当月月历如下\n", year, mouth, day);
	puts("****************************************************");

	puts("日\t一\t二\t三\t四\t五\t六");
	
	for (i = 0; i < dy; i++)
	{
		putchar('\t');
	}
	for (i = 1; i <= dd; i++)
	{
		if (i < 10)
		{
			putchar(' ');
		}

		printf("%d\t", i);

		if ((i + dy) % 7 == 0 && i != dd)
		{
			puts("");
		}
	}
	puts("");
	puts("****************************************************");
	puts("");

	while (1)
	{
		d = getchar();
		while (getchar() != '\n');
		
		switch (d)
		{
			case 'w':
				year++;
				break;
			case 's':
				year--;
				break;
			case 'a':
				mouth--;
				break;
			case 'd':
				mouth++;
				break;
			case 'q':
				goto _exit;
				break;
			default:
				puts("输入错误,请重新输入\n");
				continue;
		}

		goto loop;
	}
_exit:

	return 0;
}

运行结果如下:
输入时间,打印当月月历,输入wsad,翻动一年或一月,输入q退出
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值