/****************************************************************
>> 달력만들기 프로그램
- 년도, 월을 입력 받음
- 월의 일수를 구해야 함
- 월의 첫째 날(예: 5월 1일, 3월 1일)의 요일을 구해야 함
=> getWeekDay()함수 사용하세요
- 달력을 화면에 표시해주어야 함
>> 출력 예
<2007년 5월>
==========================
일 월 화 수 목 금 토
==========================
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
==========================
****************************************************************/
#include <stdio.h>
#define ARR_SIZE_R 6 // 배열의 행의 크기
#define ARR_SIZE_C 7 // 배열의 열의 크기
int display(void); // 초기화면 출력 함수
int input_num(void); // 입력 함수
int getWeekDay(int, int); // 각 월의 첫 요일을 구해주는 함수
int intercalary_year(int); // 윤년 구하는 함수
int calendar(int, int, int, int [][ARR_SIZE_C]); // 달력 만드는 함수
int print_cal(int, int, int, int [][ARR_SIZE_C]); // 달력 출력 함수
// 메인 함수
int main(void)
{
int arrCalendar[ARR_SIZE_R][ARR_SIZE_C]={0}; // 달력 배열 선언 (0으로 초기화)
int nYear, nMonth, nDay, intercalary, nMaxrow; // 년도, 월, 요일, 윤달, 달력의 줄 수
display(); // 초기화면 출력 함수 호출
nYear = input_num(); // 년도 입력 (입력 함수 호출)
nMonth = input_num(); // 월 입력 (입력 함수 호출)
if(nYear < 1) // 년도가 1보다 작을 경우
nYear = 1; // 년도를 1로 변경
if(nMonth > 12) // 월의 값이 12보다 클경우
nMonth = 12; // 월의 값을 12로 변경
else if(nMonth < 1) // 월의 값이 1보다 작을 경우
nMonth = 1; // 월의 값을 1로 변경
nDay = getWeekDay(nYear, nMonth); // 각 월의 첫 요일을 구해주는 함수 호출 (매개변수: 년, 월)
intercalary = intercalary_year(nYear); // 윤년을 구하는 함수 호출 (매개변수: 년)
nMaxrow = calendar(nDay, nMonth, intercalary, arrCalendar); // 달력 만드는 함수(매개변수: 첫요일, 월, 윤년여부, 달력배열)
// - 사용되는 달력(달)의 최대 줄(행)의 값 받음
print_cal(nYear, nMonth, nMaxrow, arrCalendar); // 달력 출력 함수 (매개변수: 년, 월, 달력의 줄 수, 달력배열)
return 0;
}
// 초기화면 출력 함수
int display(void)
{
puts("달력(해당 월) 출력 프로그램");
puts("===========================");
printf("년도와 월을 입력하시오(예. 2007 5) : ");
return 0;
}
// 입력 함수
int input_num(void)
{
int nNum;
scanf("%d", &nNum); // 년도나 월을 입력 받음
return nNum;
}
// 달력 만드는 함수
int calendar(int nDay, int nMonth, int intercalary, int arrCalendar[][ARR_SIZE_C])
{
int nIdx_r, nIdx_c, nCntmax, nMaxrow, nCnt=0;
if(nMonth == 2 && intercalary == 1) // 2월이고 윤년일 경우
nCntmax = 29; // 달력(월)의 최대 날짜를 29일로 지정
else if(nMonth == 2 && intercalary == 0) // 2월이고 윤년이 아닐 경우
nCntmax = 28; // 달력(월)의 최대 날짜를 28일로 지정
else if(nMonth < 8 && nMonth%2 == 1) // 2월이 아니고 8월 보다 작고 홀수 달일 경우
nCntmax = 31; // 달력(월)의 최대 날짜를 31일로 지정
else if(nMonth < 8 && nMonth%2 == 0) // 2월이 아니고 8월 보다 작고 짝수 달일 경우
nCntmax = 30; // 달력(월)의 최대 날짜를 30일로 지정
else if(nMonth >= 8 && nMonth%2 == 0) // 2월이 아니고 8월 보다 크거나 같고 짝수 달일 경우
nCntmax = 31; // 달력(월)의 최대 날짜를 31일로 지정
else if(nMonth >= 8 && nMonth%2 == 1) // 2월이 아니고 8월 보다 크거나 같고 홀수 달일 경우
nCntmax = 30; // 달력(월)의 최대 날짜를 30으로 지정
// 사용되지 않는 빈줄(행)을 반복문에서 사용하지 않게 하기 위해
if(nDay+nCntmax > 35) // 첫요일의 값과 해당 월의 최대 날짜를 더한 값이 35보다 크면
nMaxrow = 6; // 달력의 줄(행)의 수를 6으로 함
else if(nDay+nCntmax <= 28) // 첫요일의 값과 해당 월의 최대 날짜를 더한 값이 28보다 작거나 같으면(28이면)
nMaxrow = 4; // 달력의 줄(행)의 수를 4로 함
else // 그 외의 경우
nMaxrow = 5; // 달력의 줄(행)의 수를 5로 함
for(nIdx_r=0; nIdx_r<nMaxrow; nIdx_r++) // 달력의 사용되는 줄(행) 만큼 반복
{
for(nIdx_c=nDay; nIdx_c<ARR_SIZE_C; nIdx_c++) // 달력의 칸의 수 만큼 반복 [처음 초기값은 첫요일의 값으로 줌(처음 저장될 위치 조정 위해)]
{
if(nCnt < nCntmax) // 위에서 구한 해당 달의 최대 날짜 만큼만 값을 저장
{
arrCalendar[nIdx_r][nIdx_c] = ++nCnt; // 증가하면서 값 배열에 저장
}
}
nDay=0; // 배열 칸(열)이 초기값을 다시 0으로 변경 (배열의 첫 칸부터 저장할 수 있게 함)
}
return nMaxrow; // 해당월의 달력 줄 수의 값을 돌려줌
}
// 달력 출력 함수
int print_cal(int nYear, int nMonth, int nMaxrow, int arrCalendar[][ARR_SIZE_C] )
{
int nIdx_r, nIdx_c;
printf("\n\t <%d년 %d월>\n", nYear, nMonth); // 해당 년도와 달(월)을 출력
puts(" ============================");
puts(" 일 월 화 수 목 금 토 ");
puts(" ============================");
for(nIdx_r=0; nIdx_r<nMaxrow; nIdx_r++) // 인자로 받은 달력(월)에 사용된 줄(행) 만큼 반복
{
for(nIdx_c=0; nIdx_c<ARR_SIZE_C; nIdx_c++) // 배열의 칸(열)의 수 만큼 반복
{
if(arrCalendar[nIdx_r][nIdx_c] != 0) // 배열에 저장된 값이 0이 아니면
printf("%4d", arrCalendar[nIdx_r][nIdx_c]); // 각 배열 인덱스의 값 출력
else // 배열에 저장된 값이 0일 경우
printf(" "); // 공백을 출력
}
puts(""); // 줄바꿈
}
puts(" ============================");
return 0;
}
// 각 월의 첫 요일을 구해주는 함수 [현재 달력에 사용 중인 '그레고리 력' 공식]
int getWeekDay(int nYear, int nMonth)
{
int nCentury, nWDay;
if((nMonth == 1) || (nMonth == 2))
{
nYear--;
nMonth += 12;
}
// 년도를 앞의 두자리와 뒤의 두자리로 나눈다
nCentury = nYear / 100;
nYear = nYear % 100;
// 해당 월 1일의 요일 구하는 공식
nWDay = ((21 * nCentury / 4) + (5 * nYear / 4) + (26 * (nMonth + 1)) / 10) % 7;
return nWDay; // << 리턴값 >>
// 0 : 일요일 1 : 월요일 2 : 화요일 3 : 수요일
// 4 : 목요일 5 : 금요일 6 : 토요일
}
// 윤년 구하는 함수
int intercalary_year(int nYear)
{
int intercalary;
if(nYear%4 == 0)
{
if(nYear%100 == 0)
{
if(nYear%400 == 0)
intercalary = 1;
else
intercalary = 0;
}
else
intercalary = 1;
}
else
intercalary = 0;
return intercalary; // 1 : 윤년, 0 : 평년
}
[출처] [C 언어] 달력만들기|작성자 파하름
'컴퓨터 > 언어,프로그래밍' 카테고리의 다른 글
[C] 일정관리프로그램 (0) | 2009.04.04 |
---|---|
C 일정관리 프로그램 (1) | 2009.04.04 |
C언어는 날짜/시간 구하기 (0) | 2009.04.03 |
C언어 달력 - 알고리즘포함 (윤년계산) (0) | 2009.04.03 |
C언어 :: 세그멘테이션 오류 확인방법 (0) | 2009.03.30 |