UIT2024_Calendar/stu2024/数技2402樊璐瑶.cpp
2024-12-07 16:23:34 +08:00

349 lines
7.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdio.h"
#include "stdlib.h"
//判断闰年
int isLeapYear(int year)
{
if(year%400==0||(year%100!=0&&year%4==0))
{
return 1;
}
return 0;
}
// 计算某年某月的天数
int daysInMonth(int year, int month)
{
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && isLeapYear(year))
{
return 29;
}
return days[month - 1];
}
// 计算公元1年1月1日到给定日期的总天数
int totalDays(int year, int month, int day)
{
int total = 0;
for (int i = 1; i < year; i++)
{
if ((i % 4 == 0 && i % 100!= 0) || i % 400 == 0)
{
total += 366;
} else {
total += 365;
}
}
for (int i = 1; i < month; i++)
{
if (year == 1582 && i == 10)
{
// 如果是1582年且计算到10月减去10天
if (day >= 15)
{
day -= 10;
}
}
total += daysInMonth(year, i);
}
total += day;
return total;
}
// 判断输入是否为合法的数字
int isNumber(char *input)
{
for (int i = 0; input[i]!= '\0'; i++)
{
if (input[i] < '0' || input[i] > '9')
{
return 0;
}
}
return 1;
}
// 判断日期是否合法
int isValidDate(int year, int month, int day)
{
if (year <= 0)
{
return 0;
}
if (month < 1 || month > 12)
{
return 0;
}
if (day < 1 || day > daysInMonth(year, month))
{
return 0;
}
return 1;
}
//1852
int a(int year,int month,int day)
{
if(year==1582)
{
return 0;
}
if(month==10)
{
return 0;
}
if(day>4&&day<15)
{
return 0;
}
return 1;
}
// 输出一个月的日历
void printMonth(int year, int month)
{
printf(" %d年%d月\n", year, month);
printf("日 一 二 三 四 五 六\n");
int startDay = (totalDays(year, month, 1) % 7);
for (int i = 0; i < startDay; i++)
{
printf(" ");
}
int days = daysInMonth(year, month);
for (int i = 1; i <= days; i++)
{
printf("%2d ", i);
if ((totalDays(year, month, i) % 7) == 6)
{
printf("\n");
}
}
if ((totalDays(year, month, days) % 7)!= 6)
{
printf("\n");
}
}
// 获取指定日期是周几
int isWeek(int totalDay) {
return (totalDay % 7);
}
// 计算某月某天的日期
int Count_Day(int day[]) {
return (day[0] * 1000 + day[1] * 100 + day[2] * 10 + day[3]);
}
// 双列输出日历的核心函数
void printDoubleColumnCalendar(int year) {
// 对2个月分为6个块进行打印
for (int block = 0; block < 6; ++block) {
// 打印表头
printf("%2d月 %2d月 \n", block + 1, block + 7);
printf("日 一 二 三 四 五 六 日 一 二 三 四 五 六\n");
int lineEnd_l = 1, lineEnd_r = 1;
int day_l[] = {year, block + 1, 1};
int day_r[] = {year, block + 7, 1};
int totalDay_l = Count_Day(day_l);
int totalDay_r = Count_Day(day_r);
// 每个月有5行需要输出
for (int line = 0; line < 5; ++line) {
// flag作标记位每行有16个输出数字的位置第9位和16位始终置0其余位置不为0则输出数字
int flag[16] = {0};
// 标记第一行和其它行用lineEnd_L和R作为整体的日期统计
if (line == 0) {
int monthFirstday_l = isWeek(totalDay_l) + 1;
int monthFirstday_r = isWeek(totalDay_r) + 1;
for (int stringStation = monthFirstday_l; stringStation < 8; ++stringStation) {
flag[stringStation] = lineEnd_l++;
}
for (int stringStation = monthFirstday_l + 8; stringStation < 16; ++stringStation) {
flag[stringStation] = lineEnd_r++;
}
} else {
for (int stringStation = 1; stringStation < 8; ++stringStation) {
flag[stringStation] = lineEnd_l++;
if (lineEnd_l > (daysInMonth(year, block + 1))) {
break;
}
}
for (int stringStation = 9; stringStation < 16; ++stringStation) {
flag[stringStation] = lineEnd_r++;
if (lineEnd_r > (daysInMonth(year, block + 7) + 1)) {
break;
}
}
}
// 输出每行的日期
for (int i = 1; i < 16; ++i) {
if (i == 9) {
printf(" ");
}
if (flag[i] == 0) {
printf(" ");
} else {
if (flag[i] < 10) {
printf(" %d", flag[i]);
} else {
printf(" %d", flag[i]);
}
}
}
printf("\n");
}
}
}
// 菜单选项1判断闰年和星期几
void option1(void)
{
char yearStr[10], monthStr[10], dayStr[10];
int year, month, day;
// 输入年份并验证
printf("请输入年份:");
scanf("%s", yearStr);
if (!isNumber(yearStr))
{
printf("输入错误,请输入数字!\n");
return;
}
year = atoi(yearStr);
// 输入月份并验证
printf("请输入月份:");
scanf("%s", monthStr);
if (!isNumber(monthStr))
{
printf("请输入数字!\n");
return;
}
month = atoi(monthStr);
// 输入日期并验证
printf("请输入日期:");
scanf("%s", dayStr);
if (!isNumber(dayStr))
{
printf("输入错误,请输入数字!\n");
return;
}
day = atoi(dayStr);
// 验证日期整体合法性
if (!isValidDate(year, month, day))
{
printf("日期不合法!\n");
return;
}
if(!a(year,month,day))
{
printf("不存在此日期。\n");
return;
}
// 判断闰年并输出
if (isLeapYear(year))
{
printf("%d年是闰年。\n", year);
}
else
{
printf("%d年不是闰年。\n", year);
}
// 计算并输出星期几
int total = totalDays(year, month, day);
char *weekdays[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
printf("%d年%d月%d日是%s\n", year, month, day, weekdays[total % 7]);
}
// 菜单选项2输出一年的日历实现较好的双列输出
void option2(void)
{
char choiceStr[10];
int choice;
// 选择输出方式并验证
printf("请选择输出方式(1: 单列输出2: 双列输出): ");
scanf("%s", choiceStr);
if (!isNumber(choiceStr))
{
printf("输入错误,请输入数字!\n");
return;
}
choice = atoi(choiceStr);
if (choice!= 1 && choice!= 2)
{
printf("选择错误!\n");
return;
}
char yearStr[10];
int year;
// 输入年份并验证
printf("请输入年份:");
scanf("%s", yearStr);
if (!isNumber(yearStr))
{
printf("输入错误,请输入数字!\n");
return;
}
year = atoi(yearStr);
if (year <= 0)
{
printf("年份不合法!\n");
return;
}
//单列输出
if (choice == 1)
{
for (int month = 1; month <= 12; month++)
{
printMonth(year, month);
}
}
else
{
printDoubleColumnCalendar(year);
}
}
int main(void)
{
int choice;
while(choice<=2)
{
// 显示菜单并获取用户选择
printf("1. 判断闰年和星期几\n");
printf("2. 输出一年的日历\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
option1();
break;
case 2:
option2();
break;
default:
printf("退出程序\n");
break;
}
}
return 0;
}