万年历_二级指针(存在部分bug以及不完善之处)

本文介绍了一个用C语言实现的万年历程序,该程序能够根据用户输入的年份和月份显示对应月份的日历,并支持通过键盘方向键来更改年月。程序中包含了日期结构体定义、闰年判断、日期格式验证等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<STDIO.H>
#include<STDLIB.H>
#include<MALLOC.H>
#include <conio.h>
#define LEFT       75
#define RIGHT      77
#define DOWN       80
#define UP         72

typedef struct Mon{
	int month;
	int days;
}*Pmonth;
/*Create struct of Date*/
typedef struct Date{
	int year ;
	Pmonth pmon;
}*Pdate;

/*Judge if the leap year*/
bool If_leap_year(Pdate Ptr){

	if(Ptr->year%4==0 && Ptr->year%100!=0 || Ptr->year%400==0){
		return true ;
	}
	else
		return false ;
}

/*declare the function Testing_input()*/
bool Testing_input(Pdate) ;

void Month_days(Pdate Ptr){
		switch(Ptr->pmon->month){
	case 1: Ptr->pmon->days=31;break;
	case 2: 	if (If_leap_year(Ptr)){
		Ptr->pmon->days=29;
				}
		else{
			Ptr->pmon->days=28;
		}
		break;
	case 3: Ptr->pmon->days=31;break;
	case 4: Ptr->pmon->days=30;break;
	case 5: Ptr->pmon->days=31;break;
	case 6: Ptr->pmon->days=30;break;
	case 7: Ptr->pmon->days=31;break;
	case 8: Ptr->pmon->days=31;break;
	case 9: Ptr->pmon->days=30;break;
	case 10: Ptr->pmon->days=31;break;
	case 11: Ptr->pmon->days=30;break;
	case 12: Ptr->pmon->days=31;break;
	}
}
/*Input one date*/
Pdate Input_date(){
	Pdate Ptr ;
	Ptr = (Pdate)malloc(sizeof(struct Date));
	Ptr->pmon = (Pmonth)malloc(sizeof(struct Mon));
	if (!Ptr)
	{
		printf("Error!Fail to create!");
	}
	
	scanf("%d %d",&Ptr->year,&Ptr->pmon->month);
	Month_days(Ptr);

	if (Testing_input(Ptr))
	{
		return Ptr ;
	}
	else
	return NULL;
}

/*Testing the format of the date*/
bool Testing_input(Pdate Ptr){
	bool Flag;
	if((Ptr->year)<=3000 && (Ptr->year)>0){
		Flag = true ;
	}
	else{
		Flag = false ;
		printf("Please Input Year between 0~3000\n");
	}

	return Flag ;
}

int Caculate_day(Pdate Ptr){
	int day;
	int Jan=31,Feb,Mar=31,Apr=30,May=31,Jun=30,Jul=31,Aug=31,Sept=30,Oct=31,Nov=30,Dec=31 ;
	if (If_leap_year(Ptr))
	{
		Feb = 29 ;

	}
	else {
		Feb = 28 ;
	}
	switch(Ptr->pmon->month){
	case 1: day = 1;break;
	case 2: day = 1+Jan;break;
	case 3: day =1+ Jan +Feb ;break;
	case 4: day =1+ Jan +Feb+Mar;break;
	case 5: day =1+ Jan +Feb+Mar +Apr;break;
	case 6: day = 1+ Jan +Feb+Mar +Apr+May;break;
	case 7: day = 1+ Jan +Feb+Mar +Apr+May+Jun;break;
	case 8: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul;break;
	case 9:  day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug;break;
	case 10: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept;break;
	case 11: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept+Oct;break;
	case 12: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept+Oct+Nov;break;		
	}

	return day;

}

void Output_Date(Pdate Ptr){

	int i,j;
	int count=1;

	int inital=(Ptr->year-1+(Ptr->year-1)/4-(Ptr->year-1)/100+(Ptr->year-1)/400+1)%7;

	int result = (Caculate_day(Ptr)%7 + inital -1)%7;
	
	printf("%25d-%d\n",Ptr->year,Ptr->pmon->month);
	printf("    Sun    Mon    Tue    Wed    Thur    Fri    Sat     \n") ;
	for (i=0;i<6;i++){
		for (j=0;j<7;j++)
		{
			Month_days(Ptr);
			if(i==0 && j<result||count>Ptr->pmon->days) printf("       ");
			else{
				printf("%7d",count) ;
				count++;
			}
		}
		printf("\n");
	}
}

/*result=(year-1+(year-1)/4-(year-1)/100+(year-1)/400+days)%7;*/

void Which_key(Pdate ptr){
		char ch = getch();
		if(ch==-32)
		ch=getch(); 

		switch(ch) {
		case UP:
			if(ptr->pmon->month==12){
				ptr->pmon->month=1;
				ptr->year++;
			}
			else
			(ptr->pmon->month)++;
			break;
		case DOWN:
			if(ptr->pmon->month==1){
				ptr->pmon->month=12;
				ptr->year--;
			}
			else
			(ptr->pmon->month)--;;break;
		case LEFT:
			if(ptr->year==1)
				ptr->year = 3000;
			else
			 (ptr->year)--;break;
		case RIGHT:
			if(ptr->year==3000)
				ptr->year=1;
			else
				(ptr->year)++;break;
		}
}
int main(){
	
	Pdate ptr = Input_date();
	while(1){
	if(ptr){
	Output_Date(ptr);	
	}
	Which_key(ptr);
	}
	return 0;
}
</pre><pre class="objc" name="code" snippet_file_name="blog_20150424_3_2034350" code_snippet_id="652457"> 
 
时间仓促,程序存在一些需要完善的地方,基本上实现了万年历的功能,但是对于输入的处理仍然没有做相应的处理,不是很符合软件工程的设计思想。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值