2010년 4월 17일 토요일

도움말이 출력대고 특수키가 입력되는 color달력~

#include
#include
#include
#include
#include

/*특수키 code값*/
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define F1 59

/*현재날자를 구하는 구조체 및 함수 선언*/
struct date{
unsigned int da_year;
unsigned char da_mon;
unsigned char da_day;
};

void getdate(struct date *);

void draw(int,int,int,int); //박스 그리는 함수 선언
void gotoxy(int x, int y); //커서 좌표이동 함수 선언

void red(); //글자색을 빨갛게
void blue(); //글자색을 파랗게
void white(); //글자색을 하얗게

void calendar(int,int); //달력 출력 함수 선언
int yearcheck(int); //윤,평년 식별함수 선언

void onlinehelp(); //도움말을 안열었을시에 최소한의 도움말 한줄 표시 함수 선언
void helpdesk(); //도움말 함수 선언
void clrscr(int,int,int,int); //도움말 지우는 함수 선언

void main()
{
char ch, ch1; //esc의 아스키 값 27이 들어 가면 종료, codekey 저장변수선언
int num,select=0; //특수키 code값과 F1키의 눌림 확인 변수 선언

/*현재날자를 받아옴*/
struct date stdate;
getdate(&stdate);

int year = stdate.da_year, mon = stdate.da_mon; //현재 년과 월을 변수에 저장

calendar(year,mon); //현재 년월 달력 출력

onlinehelp(); //초기 한줄 도움말 표시

while(1){

ch = getch(); //키 입력받기

if(ch == 27){ break;} // Esc키 눌렸으면 종료

if(ch == -32 || ch == 0){ //특수키 값이면

ch1 = getch(); //특수키의 코드 값 받아서

num = ch1; //정수로 저장 해 놓고

if(num == F1 && select == 1){ //F1이 눌렸고 이미 눌렸을경우

clrscr(2,78,14,24); //도움말 부분 삭제
select = 0; //select를 0으로 초기화 안눌린 상태로 만들어 준다.

onlinehelp(); //초기 한줄 도움말 표시
}

else if (num == F1){ // select가 1이 아니고 F1이 눌렸을때 도움말 보여주고

select += 1; //select 를 카운터 해서 도움말창이 띄워진것을 알림

helpdesk(); //도움말 창 호출
}

switch(num){ // 특수키 코드 값을 가지고 수행하러 간다.

case UP : //전년으로 넘어가는 기능
{
year-=1;
system("cls");
calendar(year,mon);

if(select==1){ //달력을 찍었는데 도움말을 열어놨을경우 같이 보여지게 한다.
helpdesk(); // 달력부분은 화면을 다지우고 띄워야하기때문에 8개의 키값에 공통 적용
}

else{ onlinehelp(); } //도움말 창 없을 때 초기 한줄 도움말 표시 8개의 키값에 공통적용
break;
}

case DOWN : //다음년도로 넘어가는 기능
{
year+=1;
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}

case LEFT : //전월로 넘어가는기능
{
mon-=1;
if(mon < 1){ //1월 전월로 넘기는 부분 전년도 12월이 출력
year-=1;
mon=12;
}
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}

case RIGHT : //다음월로 넘어가는 기능
{
mon+=1;
if(mon > 12){ //12월 다음 월로 넘기는 부분 다음년 1월이 출력
year+=1;
mon=1;
}
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}

} //switch문 끝
} //if문 끝

else{ //일반키로 8,2,4,6이 들어올 경우

switch(ch){

case '8' : //전년으로 넘어가는 기능
{
year-=1;
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}
case '2' : //다음년도로 넘어가는 기능
{
year+=1;
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}

case '4' : //전월로 넘어가는기능
{
mon-=1;
if(mon < 1){ //1월 전월로 넘기는 부분 전년도 12월이 출력
year-=1;
mon=12;
}
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}

case '6' : //다음월로 넘어가는 기능
{
mon+=1;
if(mon > 12){ //12월 다음 월로 넘기는 부분 다음년 1월이 출력
year+=1;
mon=1;
}
system("cls");
calendar(year,mon);

if(select==1){
helpdesk();
}

else{ onlinehelp(); }
break;
}
} //switch문 끝
} //else 문 끝
}//while문 끝
}

void calendar(int year, int mon){

int totdate=0; // 총일수 저장 변수
int month[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; //각월별 일수선언 배열
int i,j,k,l=9; //loop제어 변수 선언 l는 개행좌표변수 처음에 요일 출력을 8라인에 했기때문에 9라인부터 날출력
int leap; // yearcheck함수 반환값 저장 변수



/*달력 윗부분 출력 */

gotoxy(34,6);//6라인 32번째 부터 출력
white();
printf("%d년%2d월 ",year,mon);
gotoxy(20,8); //8라인 20번째 부터 출력
white();
printf(" sun mon tue wed thu fri sat \n");

for(i = 1 ; i <= year-1 ; i++){ //전년도 까지 날수를 계산

leap = yearcheck(i);

if(leap == 1){
totdate +=366; //윤년이면 366일을 더한다
}
else{
totdate +=365;
} //평년이면 365일을 더한다
}

for(j = 0 ; j <= mon-2 ; j++){ //전달까지 날수 계산 배열첨자와 같이 돌릴려고하니까 시작이 0이대어1을더 감소

totdate += month[j]; //해달 월까지의 일수를 더한다.
}

leap = yearcheck(year);

if(leap == 1 && mon >=3) { totdate+=1; } //윤년이고 3월이 넘어가면 하루를 더한다

totdate += 1; //매달 1일의 총날수 계산

switch(totdate%7){

case 0 :{ gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

for(k=1 ; k <= month[mon-1]; k++){

if(k%7==0){blue();} //1일이 일요일부터 시작하면 토요일은 7로나누어 떨어진다.
else if(k%7==1){red();} //1일이 일요일부터 시작하면 일요일은 7로 나눌시 나머지가 1이다.
else {white();}

printf("%5d",k);

if(k%7==0) // 1일이 일요일이면 토요일날자의나머지가 0이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}
break;
case 1 :{ gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%5c",' '); // 그달시작이 월요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==6){blue();} //1일이 월요일부터 시작하면 토요일은 7로나눌시 나머지가 6이다.
else if(k%7==0){red();}//1일이 월요일부터 시작하면 일요일은 7로 나누어떨어진다.
else {white();}

printf("%5d",k);

if(k%7==6) // 1일이 월요일이면 토요일날자의나머지가 6이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}

break;

case 2 :{ gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%10c",' '); // 그달시작이 화요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==5){blue();} //1일이 화요일부터 시작하면 토요일은 7로나눌시 나머지가 5이다.
else if(k%7==6){red();}//1일이 화요일부터 시작하면 일요일은 7로 나눌시 나머지가 6이다.
else {white();}

printf("%5d",k);

if(k%7==5) // 1일이 화요일이면 토요일날자의나머지가 5이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}

break;

case 3 :{ gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%15c",' '); // 그달시작이 수요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==4){blue();} //1일이 수요일부터 시작하면 토요일은 7로나눌시 나머지가 4이다.
else if(k%7==5){red();}//1일이 수요일부터 시작하면 일요일은 7로눌시 나머지가 5이다.
else {white();}

printf("%5d",k);

if(k%7==4) // 1일이 수요일이면 토요일날자의나머지가 4이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}

break;

case 4 : { gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%20c",' '); // 그달시작이 목요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==3){blue();} //1일이 목요일부터 시작하면 토요일은 7로나눌시 나머지가 3이다.
else if(k%7==4){red();}//1일이 목요일부터 시작하면 일요일은 7로눌시 나머지가 4이다.
else {white();}

printf("%5d",k);

if(k%7==3) // 1일이 목요일이면 토요일날자의나머지가 3이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}

break;

case 5 : { gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%25c",' '); // 그달시작이 금요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==2){blue();} //1일이 금요일부터 시작하면 토요일은 7로나눌시 나머지가 2이다.
else if(k%7==3){red();}//1일이 금요일부터 시작하면 일요일은 7로눌시 나머지가 3이다.
else {white();}

printf("%5d",k);

if(k%7==2) // 1일이 금요일이면 토요일날자의나머지가 2이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}

break;

case 6 : { gotoxy(20,l); //요일 라인 다음라인부터 찍어야한다.

if(leap == 1){
month[1]=29;
} //윤달이면 그해 2월은 29일까지 이다.

printf("%30c",' '); // 그달시작이 토요일이므로 앞요일부분은 공백
for(k=1 ; k <= month[mon-1]; k++){

if(k%7==1){blue();} //1일이 토요일부터 시작하면 토요일은 7로나눌시 나머지가 1이다.
else if(k%7==2){red();}//1일이 토요일부터 시작하면 일요일은 7로눌시 나머지가 2이다.
else {white();}

printf("%5d",k);

if(k%7==1) // 1일이 수요일이면 토요일날자의나머지가 1이다
{
printf("\n");
l++;
gotoxy(20,l);
}
}
printf("\n\n");
}
break;
}//switch case 종료 괄호

}

int yearcheck(int year) //년도가 윤년인지 평년인지 알아보는 거
{

if(year%4 != 0){

return 0; //4로 나누어 떨어지지않으면 평년 0을 반환
}

else if(year%100 != 0){

return 1;//4로 나누어떨어지고 100으로 나누어떨어지지않으면 윤년 1을 반환
}

else if(year%400 != 0){

return 0; //4로 나누어 떨어지고 100으로 나누어 떨어지고 400으로 떨어지지않으면 평년 0을 반환
}

else {

return 1;//4로 나누어 떨어지고 100으로 나누어 떨어지고 400으로 떨어지면 윤년 1을 반환
}

}


void gotoxy(int x, int y) //좌표 이동 함수
{
COORD Pos = {x - 1, y - 1};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void blue() //글자색을 파랗게
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE);
}

void red() //글자색을 빨갛게
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
}
void white() //글자색을 하얗게
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN| FOREGROUND_BLUE);
}

void getdate(struct date *p) //현재 시스템 년월 아는 함수 // 원본 데이터를 변환할수 있도록 Call by pointer 기법 사용
{
char temp[128];
char *cp, syear[5]="20";
_strdate( temp ); // temp char배열 안에 08/10/04(월/일/년)순으로 년월일이 문자열 상태로 저장

cp = strtok(temp, "/"); // temp배열의 첫번째 '/'까지 문자열를 끊어내어 cp에게 "08" 문자열의 시작주소를 리턴

p->da_mon = atoi(cp); // 끊어낸 "08"문자열을 정수형 데이터 8로 변환하여 p->da_mon에 저장

cp = strtok(NULL, "/"); // temp배열의 두번째 '/'까지 문자열를 끊어내어 cp에게 "10" 문자열의 시작주소를 리턴

p->da_day = atoi(cp); // 끊어낸 "10"문자열을 정수형 데이터 10로 변환하여 p->da_day에 저장

cp = strtok(NULL, "/"); // temp배열의 세번째 '/'까지 문자열를 끊어내려하나 '/'은 나타나지 않고 문자열이
// 끝나게 되므로 남은 문자열 전체를 리턴한다 즉, cp에게 "04" 문자열의 시작주소가 리턴한다.

strcat(syear,cp); // syear내의 "20"과 cp가 가리키는 "04"을 붙여서 "2004" 문자열을 syear변수에 저장

p->da_year = atoi(syear); // syear내의 "2004" 문자열을 정수형 데이터 2004로 변환하여 p->da_year에 저장
}


void draw(int sx,int ex,int sy,int ey) //박스 만들기
{
int i,j,k;

gotoxy(sx, sy);
for(i=1 ; i <= ex-sx+1; i++){ //사각형 윗줄 시작부터 끝까지
white();
printf("*");
} //윗줄 출력

for(k=0 ; k <= ey-sy; k++){
gotoxy(sx,k+sy);
white();
printf("*");
gotoxy(ex,k+sy);
white();
printf("*");
} //왼쪽오른쪽 줄 출력
gotoxy(sx, ey);
for(j=1 ; j <= ex-sx+1; j++){
white();
printf("*");
} //아랫줄 출력

printf("\n");

}

void helpdesk() //도움말 창
{

draw(2,78,14,24); //도움말 틀을 그려서

/*도움말 출력*/
gotoxy(33,15);
printf("***도움말***");

gotoxy(17,17);
printf("1. \"↑\",\"8\" 선택시 전년도 같은 월로 이동합니다.");

gotoxy(17,18);
printf("2. \"↓\",\"2\" 선택시 다음년도 같은 월로 이동합니다.");

gotoxy(17,19);
printf("3. \"←\",\"4\" 선택시 전월로 이동합니다.");

gotoxy(17,20);
printf("4. \"→\",\"2\" 선택시 다음 월로 이동합니다.");

gotoxy(17,21);
printf("5. \"Esc\"키를 누를시 프로그램이 종료됩니다.");

gotoxy(17,23);
red();
printf("※F1키를 누르면 도움말이 종료됩니다.");
gotoxy(1,25);
white();
}

void onlinehelp() //초기 한줄 최소도움말
{
gotoxy(2,24);
white();
printf("(Esc : 종료 , F1 : 도움말)");
gotoxy(2,25);
}

void clrscr(int sx,int ex,int sy,int ey) //도움말지우기~
{
gotoxy(sx,sy);

for(int i=0 ; i for(int j=0 ; j printf(" ");
}
printf("\n");
}
}

댓글 없음:

댓글 쓰기