C Programming

C언어 입력한 년도에 따른 달력 출력 - 공부하는 도비

DOVISH WISDOM 2022. 9. 30. 16:18  
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)을 입력해도 잘 출력되는걸 볼 수 있습니다.