C语言实现万年历

在本程序中使用了结构体数组来存储多个月份的信息,结构体中除包含月份的二维数组外,还有记录模式以及其所对应的年份和月份。
程序输入的话有四个参数,第一个参数是字符串为指令,第二个参数为要查看的年份和月份,注意这里的月份占位为二,第三个参数为想从当前的月份查看后几个月,第四个参数为日期的模式,按照“一、二、三···日”的顺序还是“日、一、二···六”的顺序。(参数已经实现校验功能,后两个参数有默认值,可不用输入~

tips:
1.日历的表头”一“”二“”三“···使用二维字符数组来存储
2.ASC码为32的时候输出的是空格

程序运行结果展示:
在这里插入图片描述
程序源代码:

#include<stdio.h>
#include<time.h>
#include<string.h>
//定义日历结构体
struct calendar {
	//参数p3,1为从周一开始,0为从周日开始, 默认从周一开始
	int p3=1;
	//当前日历的年份和月份
	int year;
	int month;
	//声明数组并初始化
	int data[5][7]= {{32,32,32,32,32,32,32},{32,32,32,32,32,32,32},{32,32,32,32,32,32,32},{32,32,32,32,32,32,32},{32,32,32,32,32,32,32}};
};
//按照格式打印输出
void print(struct calendar calendarList[],int count);
//计算与原点相差的天数
int week();
//填充数据
void fill(struct calendar calendarList[],int count,int week);
//判断是闰年还是平年的函数
int judge(int year);
//全局变量 年,月,与相差的天数
int year,month,sum=0;
//闰年和平年每个月的天数
int leap[12]= {31,29,31,30,31,30,31,31,30,31,30,31};
int ordinary[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
int main() {
	long start,end;//定义计时变量
	char s[66];
	char mode[66];
	//记录输出几个月
	int count;
	int check;
	char c1,c2,c3;
	while(1) {
		sum=0;
		check=1;
		//传入参数,用字符数组接收
		scanf("%s",&s);
		c3=getchar();
		if (c3=='\n') {
			printf("--help:mycalendar 202203 5 mon(P3 P4默认值为:12 mon)\n");
		} else {
			//输入开始的年份和月份
			scanf("%4d%2d",&year,&month);
			c1=getchar();
			if (c1=='\n') {
				//赋初值
				count=12;
				mode[0]='m',mode[1]='o',mode[2]='n',mode[3]='\0';
			} else {
				//输入要从当前月份开始几个月
				scanf("%d",&count);
				c2=getchar();
				if (c2!='\n') {
					//输入模式
					scanf("%s",&mode);
				} else {
					mode[0]='m',mode[1]='o',mode[2]='n',mode[3]='\0';
				}
			}
			//直接声明数量为count的结构体数组
			if (strcmp(s,"mycalendar")!=0) {
				printf("%s不是内部命令\n--help:mycalendar 202203 5 mon(P3 P4默认值为:12 mon)\n",s);
				check=0;
			}
			if (year<=0||month<=0) {
				printf("输入的年份或月份不合法\n--help:mycalendar 202203 5 mon(P3 P4默认值为:12 mon)\n");
				check=0;
			}
			if (count<=0) {
				printf("输入的count不合法\n--help:mycalendar 202203 5 mon(P3 P4默认值为:12 mon)\n");
				check=0;
			}
			if ((strcmp(mode,"mon")!=0)&&(strcmp(mode,"sun")!=0)) {
				printf("输入的mode不合法\n--help:mycalendar 202203 5 mon(P3 P4默认值为:12 mon)\n--help:mycalendar 202203 5 sun(P3 P4默认值为:12 mon)\n");
				check=0;
			}
			if (check) {
				struct calendar calendarList[count];
				//如果要从周日开始的话,需要改变一下参数
				if (strcmp(mode,"sun")==0) {
					for (int i=0; i<count; i++) {
						calendarList[i].p3=0;
					}
				}
				//程序开始
				start=clock();
				//由已知原点算出当前的原点
				fill(calendarList,count,week());
				print(calendarList,count);
				//程序结束
				end=clock();
				printf("执行时长:%ldms\n",end-start);
			}
		}
	}
	return 0;
}
//打印
void print(struct calendar calendarList[],int count) {
	int i=0;
	//若为mon模式
	if (calendarList[0].p3==1) {
		while(count!=0) {
			if (count>=3) {
				printf("\n%d年%d月\t\t\t%d年%d月\t\t\t%d年%d月",calendarList[i].year,calendarList[i].month,calendarList[i+1].year,calendarList[i+1].month,calendarList[i+2].year,calendarList[i+2].month);
				printf("\n一  二  三  四  五  六  日\t一  二  三  四  五  六  日\t一  二  三  四  五  六  日\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+1].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+1].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+2].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+2].data[j][k]);
						}
					}
					printf("\n");
				}
				i+=3;
				count-=3;
			} else if (count==1) {
				printf("\n%d年%d月",calendarList[i].year,calendarList[i].month);
				printf("\n一  二  三  四  五  六  日\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\n");
				}
				count-=1;
			} else if (count==2) {
				printf("\n%d年%d月\t\t\t%d年%d月",calendarList[i].year,calendarList[i].month,calendarList[i+1].year,calendarList[i+1].month);
				printf("\n一  二  三  四  五  六  日\t一  二  三  四  五  六  日\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+1].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+1].data[j][k]);
						}
					}
					printf("\n");
				}
				count-=2;
			}
		}
	}
	//若为sun模式
	else {
		while(count!=0) {
			if (count>=3) {
				printf("\n%d年%d月\t\t\t%d年%d月\t\t\t%d年%d月",calendarList[i].year,calendarList[i].month,calendarList[i+1].year,calendarList[i+1].month,calendarList[i+2].year,calendarList[i+2].month);
				printf("\n日  一  二  三  四  五  六\t日  一  二  三  四  五  六\t日  一  二  三  四  五  六\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+1].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+1].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+2].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+2].data[j][k]);
						}
					}
					printf("\n");
				}
				i+=3;
				count-=3;
			} else if (count==1) {
				printf("\n%d年%d月",calendarList[i].year,calendarList[i].month);
				printf("\n日  一  二  三  四  五  六\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\n");
				}
				count-=1;
			} else if (count==2) {
				printf("\n%d年%d月\t\t\t%d年%d月",calendarList[i].year,calendarList[i].month,calendarList[i+1].year,calendarList[i+1].month);
				printf("\n日  一  二  三  四  五  六\t日  一  二  三  四  五  六\n");
				for (int j=0; j<5; j++) {
					for (int k=0; k<7; k++) {
						if (calendarList[i].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i].data[j][k]);
						}
					}
					printf("\t");
					for (int k=0; k<7; k++) {
						if (calendarList[i+1].data[j][k]==32) {
							printf("    ");
						} else {
							printf("%-4d",calendarList[i+1].data[j][k]);
						}
					}
					printf("\n");
				}
				count-=2;
			}
		}
	}
}
int week() {
	//2021年1月1日是星期五,初始化为星期五
	int day=5;
	//定义余数和星期的对照表
	int y1[7]= {5,6,7,1,2,3,4};
	int y2[7]= {5,4,3,2,1,7,6};
	//如果是在2021年1月之后的时间的话,那么正着算
	if ((year>2021)||((year==2021)&&(month>1))) {
		//首先计算年天数
		for (int i=2021; i<year; i++) {
			if (judge(i)) {
				sum+=366;
			} else {
				sum+=365;
			}
		}
		//然后计算月份天数
		for (int i=0; i<month-1; i++) {
			if (judge(year)) {
				sum+=leap[i];
			} else {
				sum+=ordinary[i];
			}
		}
		//计算余数,根据对照表来计算出星期几
		day=y1[sum%7];
		return day;
	}
	//如果正好是2021年的1月的话,直接返回day
	else if ((year==2021)&&(month==1)) {
		return day;
	}
	//如果在2021年之前的话,倒着算
	else {
		//首先计算月份
		for (int i=month-1; i<12; i++) {
			if (judge(year)) {
				sum+=leap[i];
			} else {
				sum+=ordinary[i];
			}
		}
		//然后计算年份
		for (int i=year+1; i<2021; i++) {
			if (judge(i)) {
				sum+=366;
			} else {
				sum+=365;
			}
		}
		//计算余数,根据对照表来计算出星期几
		day=y2[sum%7];
		return day;
	}
}
int judge(int year) {
	if (((year%4==0)&&(year!=100))||(year%400==0)) {
		return 1;
	} else {
		return 0;
	}
}
void fill(struct calendar calendarList[],int count,int week) {
	//定义池子变量
	int pond;
	int o;
	int week2;
	//若填充模式为mon的话
	if (calendarList[0].p3==1) {
		for (int i=0; i<count; i++) {
			//此时的池子为模式1的池子
			pond=36-week;
			//如果当前年份是闰年的话
			if (judge(year)) {
				//如果池子能装下的话
				if (pond>=leap[month-1]) {
					//首先填充第一行
					o=1;
					for (int n=week-1; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							if (o>leap[month-1]) {
								break;
							}
							calendarList[i].data[m][n]=o;
							o++;
						}
						if (o>leap[month-1]) {
							break;
						}
					}
				} else {
					//首先填充第一行
					o=pond+1;
					for (int n=0; n<leap[month-1]-pond; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					o=1;
					for (int n=week-1; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行,不用考虑填不满的情况
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							calendarList[i].data[m][n]=o;
							o++;
						}
					}
				}
				//更新week变量
				week=((leap[month-1]%7)+week)%7;
				if (week==0) {
					week=7;
				}
			}
			//如果是平年的话
			else {
				//如果池子能装下的话
				if (pond>=ordinary[month-1]) {
					//首先填充第一行
					o=1;
					for (int n=week-1; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							if (o>ordinary[month-1]) {
								break;
							}
							calendarList[i].data[m][n]=o;
							o++;
						}
						if (o>ordinary[month-1]) {
							break;
						}
					}
				} else {
					//首先填充第一行
					o=pond+1;
					for (int n=0; n<ordinary[month-1]-pond; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					o=1;
					for (int n=week-1; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行,不用考虑填不满的情况
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							calendarList[i].data[m][n]=o;
							o++;
						}
					}
				}
				//更新week变量
				week=((ordinary[month-1]%7)+week)%7;
				if (week==0) {
					week=7;
				}
			}
			//如果是第一年的话,直接赋值
			calendarList[i].year=year;
			calendarList[i].month=month;
			month++;
			//若月份大于12的话,新的一年开始
			if (month>12) {
				year++;
				month=1;
			}
		}
	}
	//如果填充模式为sun的话
	else {
		for (int i=0; i<count; i++) {
			//此时的池子为模式0的池子
			if(week!=7) {
				pond=35-week;
			} else {
				pond=35;
			}
			//如果当前年份是闰年的话
			if (judge(year)) {
				//如果池子能装下的话
				if (pond>=leap[month-1]) {
					//首先填充第一行
					o=1;
					week2=week;
					if (week2==7) {
						week2=0;
					}
					for (int n=week2; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							if (o>leap[month-1]) {
								break;
							}
							calendarList[i].data[m][n]=o;
							o++;
						}
						if (o>leap[month-1]) {
							break;
						}
					}
				} else {
					//首先填充第一行
					o=pond+1;
					for (int n=0; n<leap[month-1]-pond; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					o=1;
					week2=week;
					if (week2==7) {
						week2=0;
					}
					for (int n=week2; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行,不用考虑填不满的情况
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							calendarList[i].data[m][n]=o;
							o++;
						}
					}
				}
				//更新week变量
				week=((leap[month-1]%7)+week)%7;
				if (week==0) {
					week=7;
				}
			}
			//如果是平年的话
			else {
				//如果池子能装下的话
				if (pond>=ordinary[month-1]) {
					//首先填充第一行
					o=1;
					week2=week;
					if (week2==7) {
						week2=0;
					}
					for (int n=week2; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							if (o>ordinary[month-1]) {
								break;
							}
							calendarList[i].data[m][n]=o;
							o++;
						}
						if (o>ordinary[month-1]) {
							break;
						}
					}
				} else {
					//首先填充第一行
					o=pond+1;
					for (int n=0; n<ordinary[month-1]-pond; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					o=1;
					week2=week;
					if (week2==7) {
						week2=0;
					}
					for (int n=week2; n<7; n++) {
						calendarList[i].data[0][n]=o;
						o++;
					}
					//填充下边四行,不用考虑填不满的情况
					for (int m=1; m<5; m++) {
						for (int n=0; n<7; n++) {
							calendarList[i].data[m][n]=o;
							o++;
						}
					}
				}
				//更新week变量
				week=((leap[month-1]%7)+week)%7;
				if (week==0) {
					week=7;
				}
			}
			//如果是第一年的话,直接赋值
			calendarList[i].year=year;
			calendarList[i].month=month;
			month++;
			//若月份大于12的话,新的一年开始
			if (month>12) {
				year++;
				month=1;
			}
		}
	}
}
  • 20
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值