//This program is a perpetual calendar implemented using the year calculation method;
//The code contains a lot of comments for readers to read;
//Use the C standard library (portable program);
//Can run under Linux/Mac os/Windows;
// Plagiarism and reprinting without permission is strictly prohibited;
//If it is helpful to you, please like, favorite or forward;
//The source code is here, I hope to inspire you;
//C language perpetual calendar applet.c
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
/*函数功能:判断是否是闰年*/
bool is_leap_year(int year);
/*-------------------------------------*/
/*函数功能:打印n个空格数*/
void print_space(int n);
/*-------------------------------------*/
/*函数功能:计算当前年份第一天是星期几*/
int day_of_week(int year);
/*-------------------------------------*/
/*函数功能:将数字转化成对应的汉字月份*/
char *print_month(int month);
/*-------------------------------------*/
/*函数功能:输出日历中每月份的表头*/
void print_head_of_month(int month);
/*-------------------------------------*/
/*函数功能:打印当前年份的日历*/
void print_calendar(int year);
/*-------------------------------------*/
/*函数功能:判断用户输入是否正确*/
int get_correct_choice(void);
/*-------------------------------------*/
/*函数功能:获取用户输入*/
int get_first(void);
/*-------------------------------------*/
int main(void)
{
int ch, year;
do
{
printf("=====================================\n");
puts(" 欢迎进入万年历查询系统!");
printf("=====================================\n");
printf("请输入您要查询的年份:");
scanf("%d", &year);
printf("\n\n\n\n\n\n\n\n\n\n\n");
print_calendar(year);
printf("您希望继续查询吗?(y/n)\n");
printf("请您输入选择:");
ch = get_correct_choice();
} while (ch != 'n');
puts("欢迎下次使用!");
return 0;
}
bool is_leap_year(int year)
{
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? true : false;
//4年为一闰年,100年不是闰年,而400年又是一闰年;
}
void print_space(int n)
{
while (n--)
{
printf(" ");
}
return;
}
int day_of_week(int year)
{
return ((year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400) % 7);
//公元元年的第一天是星期一,后面每一年与公元元年的差值再对7取余数即可得到当前年份的第一天是星期几;
}
char *print_month(int month)
{
char *month_names[] = {
"一月", "二月", "三月", "四月",
"五月", "六月", "七月", "八月",
"九月", "十月", "十一月", "十二月"};
return (month > 0 && month < 13) ? month_names[month - 1] : " ";
}
void print_head_of_month(int month)
{
print_space(12);
printf("%s", print_month(month)); //打印的是奇数月份的名称;
print_space(28); //空格隔开两月月历的表头部分;
printf("%s \n", print_month(month + 1)); //打印的是偶数月份的名称;
printf("_____________________________");
print_space(5); //空格隔开两月月历的表头部分;
printf("_____________________________\n");
printf(" 日 一 二 三 四 五 六");
print_space(6); //空格隔开两月月历的表头部分;
printf(" 日 一 二 三 四 五 六\n");
return;
}
void print_calendar(int year)
{
bool odd, even;
int i, j, k, m, n, days;
int a[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
print_space(26);
printf("%d年日历表\n\n", year);
days = day_of_week(year); //计算当前年份第一天是星期几;
if (is_leap_year(year))
{
++a[2]; //闰年则2月份增加一天;
}
for (i = 1; i < 13; i += 2)
{
m = n = 0; //累计奇偶月份的天数;
odd = even = false; //判断奇偶月份的月历是否打印完成;
print_head_of_month(i); //输出月历的表头;
for (j = 0; j < 6; j++) //每月月历最多是6行;
{
if (0 == j) //定位每月第一行的每月1日的输出位置;
{
print_space(days * 4);
for (k = 0; k < 7 - days; k++) //打印第i月的第一行日期;
{
printf("%4d", ++m);
}
print_space(6); //奇偶月份日期用空格分隔;
days = (days + a[i] % 7) % 7;
//判断右半部分偶数月份的第i + 1月 1 日是星期几,a[i]是上个月(奇数月份第i月)的总天数;
print_space(days * 4);
for (k = 0; k < 7 - days; k++) //打印第i + 1月的第一行日期;
{
printf("%4d", ++n);
}
putchar('\n');
}
else
{
for (k = 0; k < 7; k++) //左半部分打印奇数月份的第i月的日期(2-6行);
{
if (m < a[i])
{
printf("%4d", ++m);
}
else
{
print_space(4);
}
if (m == a[i])
{
odd = true; //标记奇数月份打印完成;
}
}
print_space(6);
for (k = 0; k < 7; k++) //右半部分打印偶数月份的第i + 1月的日期(2-6行);
{
if (n < a[i + 1])
{
printf("%4d", ++n);
}
else
{
print_space(4);
}
if (n == a[i + 1])
{
even = true; //标记偶数月份打印完成;
}
}
putchar('\n');
if (odd && even)
{
break; //所有月份都打印完成则退出循环;
}
}
}
putchar('\n');
days = (days + a[i + 1] % 7) % 7;
//判断下月1日是星期几,a[i + 1]是上个月(偶数月份第i + 1月)的总天数;
}
return;
}
int get_correct_choice(void)
{
int ch;
ch = get_first();
while (ch != 'y' && ch != 'n')
{
printf("输入无效!请输入y或者n:");
ch = get_first();
}
return ch;
}
int get_first(void)
{
int ch;
do
{
ch = getchar();
} while (isspace(ch));
while (getchar() != '\n')
continue;
return ch;
}
//-------------
//----------------------------August 2, 2020-------------- -----------------