언어 자료구조 알고리즘/[C++]디딤돌 자료구조와 알고리즘

3.1.1 이 책에서 공통으로 사용하는 것들 [디딤돌 자료구조와 알고리즘 with C++]

언제나휴일 2016. 4. 4. 10:21
반응형

3.1.1 이 책에서 공통으로 사용하는 것들

앞으로 이 책에서 사용할 클래스 ehglobal을 소개를 하겠습니다. ehglobal 클래스에는 이 책에 소개되는 전반적인 예제 프로그램에서 공통으로 사용할 만한 함수들을 정적 멤버 메서드로 캡슐화되어 있습니다. 이 책에 공통으로 사용 가능한 것들에 대한 정의에서는 형식 명과 메서드 명 모두 소문자만을 사용하고 있습니다.

class ehglobal

{

public:

콘솔 화면을 지우는 메서드를 제공합시다.

    static void clrscr();//화면을 지우는 메서드

시간을 지연시키는 메서드도 제공합시다.

    static void timeflow(int millisecond); //원하는 시간동안 지연시키는 메서드

정수를 입력받는 메서드도 제공합시다.

    static int getnum();//정수를 입력받는 메서드

문자열을 입력받는 메서드도 제공합시다.

    static string getstr();//문자열을 입력받는 메서드

기능 키를 입력받는 메서드를 제공합시다.

    static int getkey();//기능 키를 입력받는 메서드

private:

정적 메서드를 사용하기 위해 정의한 클래스로 생성자와 소멸자는 private으로 접근 지정하세요.

    ehglobal(void){ }//개체를 생성하지 못하게 하기 위해 private으로 접근 지정

    ~ehglobal(void){}

};

 

 

clrscr 메서드는 단순히 콘솔 화면을 지우는 cls 명령을 system 함수를 이용하는 호출하는 것 밖에 없어요. 여기에서는 자주 사용하는 함수들을 ehglobal 클래스의 정적 멤버 메서드로 캡슐화하여 사용자 편의를 제공하는 것 외에는 특별한 의미가 없습니다. 여러분께서 의미 없다고 생각하시면 무시하셔도 상관없어요.

void ehglobal::clrscr()//화면을 지우는 메서드

{

    system("cls");

}

 

timeflow 메서드는 Windows API에서 제공하는 Sleep을 이용하여 원하는 시간동안 지연시킵니다.

void ehglobal::timeflow(int millisecond) //원하는 시간동안 지연시키는 메서드

{

    Sleep(millisecond);

}

 

정수를 입력받는 메서드로 getnum을 구현합시다. istream 개체인 cin을 사용하여 cin>>num; 처럼 정수를 입력받으면 사용자가 정수가 아닌 다른 문자를 입력하면 버퍼에 계속 남아있어 이후의 입력에서 문제가 발생할 수 있어요.

 

여기에서는 cin개체의 getline 메서드로 사용자가 입력한 stream을 지역 변수에 입력받은 후에 버퍼를 지우고 입력한 내용을 정수로 변환하여 반환할게요.

 

참고로 stream은 아스키코드의 연속된 나열로써 연속의 끝은 '\n'입니다. 그리고 문자열은 '\0'가 오기 전까지의 아스키코드의 연속된 나열입니다.

int ehglobal::getnum()//정수를 입력받는 메서드

{

    int num;

    char buf[255+1];

    cin.getline(buf,255);

    cin.clear();

    sscanf(buf,"%d",&num);

    return num;

}

 

문자열을 입력받는 메서드로 getstr을 구현합시다. 마찬가지로 cin>>name; 과 같은 형태로 문자열을 입력받으면 공백이나 탭이 중간에 입력하면 그 이전까지만 입력받습니다. 그리고 입력 버퍼에는 여전히 그 이후의 문자들이 남아있어 다음 입력 요청에 문제가 발생할 수 있어요. 이를 방지하기 위해 getstr을 제공합시다.

string ehglobal::getstr()//문자열을 입력받는 메서드

{

    char buf[255+1];

    cin.getline(buf,255);

    cin.clear();

    return buf;

}

 

그리고 메뉴를 입력받는 작업과 같이 기능 키를 입력받기 위한 메서드 getkey를 제공하겠습니다. 여기에서는 F1~F10까지와 ESC를 제공하기로 하겠습니다.

 

먼저 이와 같은 키를 사용하기 쉽게 열거형 keydata로 정의하세요.

enum keydata

{

    NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,ESC

};

 

 

 

 

 

기능 키를 입력받는 메서드에서는 사용자로부터 입력받은 키를 keydata 형식에 열거된 값으로 변환하여 반환하도록 하겠습니다.

 

getch 함수를 호출하였을 때 ESC 키를 누르면 27을 반환합니다. , getch 함수가 반환하는 값이 27인 경우에는 keydata 형식에 열거된 ESC를 반환하게 하였습니다.

 

int ehglobal::getkey()//기능 키를 입력받는 메서드

{

    int key = getch();

getch 함수는 호출하였을 때 ESC키를 누르면 27을 반환하므로 이 때는 ESC를 반환하세요.

    if(key == 27) //ESC를 누를 때의 key 값이 27

    {

        return ESC;

    }

기능 키를 누르면 0을 반환합니다.

    if(key == 0) //기능 키를 눌렀을 때는 getch의 반환값이 0

    {

어떤 기능 키를 누른 것인지 확인하려면 다시 getch 함수를 호출해야 합니다.

        //어떤 기능 키를 눌렀는지 확인하려면 getch를 다시 호출해야 함

        //사용자에게 다시 키를 입력받는 것은 아님

        key = getch();

그리고 반환받은 값에 따라 이에 해당하는 기능 키를 반환합니다.

        switch(key) //입력한 키에 따라 약속된 값 반환

        {

        case 59: return F1;    case 60: return F2;

        case 61: return F3;    case 62: return F4;

        case 63: return F5;    case 64: return F6;

        case 65: return F7;    case 66: return F8;

        case 67: return F9;    case 68: return F10;

        }

    }

keydata에 열거하지 않은 키를 눌렀을 때는 NO_DEFINED를 반환합시다.

    return NO_DEFINED; //열거되지 않은 키를 눌렀을 때

}

 

 

다음은 공통으로 사용할 ehglobal.h ehglobal.cpp 파일에 작성한 내용입니다.

//ehglobal.h

#pragma once

#pragma warning(disable:4996)

#include <string>

using std::string;

#include <iostream>

using std::cout;

using std::cin;

using std::ostream;

using std::endl;

#include <conio.h>

#include <windows.h>

enum keydata

{

    NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,ESC

};

 

//공통적으로 사용할 정적 메서드를 캡슐화한 클래스

class ehglobal

{

public:

    static void clrscr();//화면을 지우는 메서드

    static void timeflow(int millisecond); //원하는 시간동안 지연시키는 메서드

    static int getnum();//정수를 입력받는 메서드

    static string getstr();//문자열을 입력받는 메서드

    static int getkey();//기능 키를 입력받는 메서드

private:

    ehglobal(void){ }//개체를 생성하지 못하게 하기 위해 private으로 접근 지정

    ~ehglobal(void){}

};

 

//ehglobal.cpp

#include "ehglobal.h"

void ehglobal::clrscr()//화면을 지우는 메서드

{

    system("cls");

}

void ehglobal::timeflow(int millisecond) //원하는 시간동안 지연시키는 메서드

{

    Sleep(millisecond);

}

 

int ehglobal::getnum()//정수를 입력받는 메서드

{

    int num;

    char buf[255+1];

    cin.getline(buf,255);

    cin.clear();

    sscanf(buf,"%d",&num);

    return num;

}

 

string ehglobal::getstr()//문자열을 입력받는 메서드

{

    char buf[255+1];

    cin.getline(buf,255);

    cin.clear();

    return buf;

}

 

int ehglobal::getkey()//기능 키를 입력받는 메서드

{

    int key = getch();

 

    if(key == 27) //ESC를 누를 때의 key 값이 27

    {

        return ESC;

    }

    if(key == 0) //기능 키를 눌렀을 때는 getch의 반환값이 0

    {

        //어떤 기능 키를 눌렀는지 확인하려면 getch를 다시 호출해야 함

        //사용자에게 다시 키를 입력받는 것은 아님

        key = getch();

        switch(key) //입력한 키에 따라 약속된 값 반환

        {

        case 59: return F1;    case 60: return F2;

        case 61: return F3;    case 62: return F4;

        case 63: return F5;    case 64: return F6;

        case 65: return F7;    case 66: return F8;

        case 67: return F9;    case 68: return F10;

        }

    }

    return NO_DEFINED; //열거되지 않은 키를 눌렀을 때

}

반응형