728x90
반응형
오늘은 입력한 년도에 따른 달력을 출력해보겠습니다.
달력 출력하기를 위해선,
윤년/평년 계산과 1월 1일이 무슨 요일로 시작되는지 알아야 합니다.
코드는 다음과 같습니다.
- 함수 LeapYear은 윤년/ 평년 판단 함수입니다.
- GetStart는 입력된 년도의 1월 1일이 무슨 요일로 시작되는지 알아내는 함수입니다.
- PrintMonth는 달력을 출력하는 함수입니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int LeapYear(int year);
void PrintMonth(int check, int start_point);
int GetStart(int year);
int main()
{
int input_year;
scanf("%d", &input_year);
PrintMonth(input_year, GetStart(input_year));
return 0;
}
int GetStart(int year) // 년도를 입력했을 때, 1월 1일이 무슨 요일인지 계산하는 함수
{ // (일요일 : 0), (월요일 : 1), (화요일 : 2), (수요일 : 3), (목요일 : 4), (금요일 : 5), (토요일 : 6)
int ref_year = 1900, leap = 0, diff, total_days = 0, day = 0;
diff = year - ref_year;
while (ref_year < year)
{
if (ref_year % 100 == 0)
{
if (ref_year % 400 == 0)
{
leap++;
}
}
else
{
if (ref_year % 4 == 0)
{
leap++;
}
}
ref_year++;
}
total_days = (diff - leap) * 365 + leap * 366;
day = (total_days + 1) % 7;
return day;
}
int LeapYear(int year) // 윤년, 평년 계산 함수
{ // (윤년 : 1 return), (평년 : 0 return)
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return 1;
else
return 0;
}
void PrintMonth(int year, int start_point) // 달력 출력 함수
{ // 입력된 년도와 1월 1일이 무슨 요일부터 시작하는 지에 해당하는 start_point를 입력으로 받는다.
int month_arr[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // 각 월 별에 해당하는 날짜를 배열로 저장해둔다. (ex 1월은 31일까지)
// default 로 2월은 평년 (28일까지)으로 저장해둔다.
if (LeapYear(year) == 1) { month_arr[1] += 1; } // 함수 LeapYear의 반환 값에 따라 윤년이면, month_arr[1] (2월에 해당)에 +1 일을 해준다.
int end_point = 0; // start_point와 반대되는 변수로, 1월 1일이 토요일(배열 넘버 : 6) 부터 시작하면 31일이 월요일로 끝나게 됨 (배열 넘버 : 0).
// 31일(or 30, 29, 28)이 끝나는 요일을 저장 (일요일 : 0), (월요일 : 1), (화요일 : 2), (수요일 : 3), (목요일 : 4), (금요일 : 5), (토요일 : 6)
int cnt = 1;
int i, j;
for (int p = 1; p <= 12; p++) // 1월 부터 12월 까지 출력하기 위한 반복문
{
int week[6][7] = { 0, }; // 2차원 배열 week 는 달력을 봤을 때, 보이는 형태를 나타내기 위함. 처음엔 0으로 초기화 해둠.
printf("%d월\n", p);
printf("SUN MON TUS WED THU FRI SAT\n");
printf("===================================================\n");
for (i = 0; i < 6; i++) // 반복되는 주
{
if (i == 0) // (1주차에 해당) start_point에 따라 1일이 시작하는 요일부터 배열 week 에 날짜 입력
{ // cnt를 올리면서, 1일 부터 달의 마지막 날까지 입력
for (int j = start_point; j < 7; j++)
{
week[i][j] = cnt++;
}
}
else // (2주차 이상에 해당)
{
for (j = 0; j < 7; j++)
{
week[i][j] = cnt++;
if (cnt == month_arr[p - 1] + 1) // 달의 마지막 날까지 입력 받았으면 break로 2중 반복문을 빠져나옴
{
end_point = j; // 달의 마지막 날이 무슨 요일에 끝났는지 end_point에 저장. ( 다음 달의 start_point로 넘겨주기위함)
break;
}
}
}
if (cnt == month_arr[p - 1] + 1) { break; } // 달의 마지막 날까지 입력 받았으면 break로 2중 반복문을 빠져나옴
}
for (i = 0; i < 6; i++) // 2차원 배열 week를 출력
{ // 0으로 초기화 한 부분은 출력할 필요 없으니, 배열의 원소가 0일 땐 출력하지 않는것으로 한다.
if (i == 5 && week[5][0] == 0) { break; }
for (j = 0; j < 7; j++)
{
if (week[i][j] == 0) { printf("\t"); }
else { printf("%d\t", week[i][j]); }
}
printf("\n");
}
start_point = (end_point + 1) % 7; // ex) 1월 31일이 화요일에 끝났으면, 2월 1일은 수요일에 시작하게 하기 위함
cnt = 1;
printf("\n");
}
}
올해 년도인 2022를 입력하면, 아래처럼 달력이 이쁘게 출력되는 걸 확인할 수 있습니다.
다른 년도(ex, 2000)을 입력해도 잘 출력되는걸 볼 수 있습니다.
'C Programming' 카테고리의 다른 글
C언어 포인터 기초 (선언) - 공부하는 도비 (0) | 2022.10.13 |
---|---|
C언어 행렬 곱셈 - 공부하는 도비 (1) | 2022.10.03 |
C언어 2차원 배열의 합 - 공부하는 도비 (0) | 2022.10.03 |
C언어 공백 포함 문자열 입력 받기 (scanf, gets) - 공부하는 도비 (0) | 2022.10.03 |
visual studio scanf 오류 해결 방법 5가지 - 공부하는 도비 (1) | 2022.09.30 |