3.1.6 vector를 인덱스 연산으로 사용 예제

앞에서 실습한 vectorㄹ르 인덱스 연산으로 사용하는 예제 소스 코드입니다.

//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; //열거되지 않은 키를 눌렀을 때
}
//Genre.h
#pragma once
#include "ehglobal.h"
class Genre
{
    string name;
    const int num;
public:
    Genre(int num,string name);
    int GetNum()const;
    string GetName()const;
    void View()const;
};

#include "Genre.h"

Genre::Genre(int num,string name):num(num)
{
    this->name = name;
}
int Genre::GetNum()const
{
    return num;
}
string Genre::GetName()const
{
    return name;
}
void Genre::View()const
{
    cout<<"장르 No."<<num<<" 장르명:"<<name<<endl;
}
//App.h
#pragma once
#include "Genre.h"
#include "ehglobal.h"
#include <vector>
#include <algorithm>
using std::vector;
using std::find;
using std::find_if;

typedef vector<Genre *> Genres;
typedef Genres::iterator GIter;
typedef Genres::const_iterator GCIter;


class App
{
    Genres genres;
    int max_genres;//최대 장르 번호
public:
    App(void);
    ~App(void);
    void Run();
private:
    int SelectMenu();
    void AddGenre(); //장르 추가
    void RemoveGenreByNum();//번호로 장르 삭제
    void RemoveGenreByName();//이름으로 장르 삭제
    void FindGenreByNum()const; //번호로 장르 검색
    void FindGenreByName()const; //이름으로 장르 검색
    void ListGenre()const; //장르 목록 보기
};
//App.cpp
#include "App.h"

class EqualerByName
{
    string name;
public:
    EqualerByName(string name)
    {
        this->name = name;
    }
    bool operator()(const Genre *genre)const
    {
        if(genre==0)
        {
            return false;
        }
        return name.compare(genre->GetName())==0;
    }
};

App::App(void)
{
    cout<<"최대 장르 번호:";
    max_genres = ehglobal::getnum();
    genres.resize(max_genres,0);//max_genres 만큼 0으로 보관(설정)
}


App::~App(void)
{
    for(int i = 0; i<max_genres; i++)
    {
        if(genres[i])
        {
            delete genres[i];
        }
    }
}

void App::Run()
{
    int key=NO_DEFINED;
    while((key = SelectMenu())!=ESC)
    {
        switch(key)
        {
        case F1: AddGenre(); break;
        case F2: RemoveGenreByNum(); break;
        case F3: RemoveGenreByName(); break;
        case F4: FindGenreByNum(); break;
        case F5: FindGenreByName(); break;
        case F6: ListGenre(); break;
        default: cout<<"잘못 선택하셨습니다."<<endl; break;
        }
        cout<<"아무 키나 누르세요."<<endl;
        ehglobal::getkey();
    }
}

int App::SelectMenu()
{
    ehglobal::clrscr();//콘솔 화면을 지우기
    cout<<"장르 관리 프로그램 [ESC]: 종료"<<endl;
    cout<<"F1: 장르 추가 F2: 번호로 장르 삭제 F3: 이름으로 장르 삭제"<<endl;
    cout<<"F4: 번호로 장르 검색 F5: 이름으로 장르 검색 F6: 장르 목록 보기"<<endl;

    return ehglobal::getkey();//사용자가 입력한 기능 키 반환
}

void App::AddGenre() //장르 추가
{
    int num=0;
    cout<<"추가할 장르 번호(1~"<<max_genres<<"):";
    num = ehglobal::getnum();
    if((num<=0)||(num>max_genres))
    {
        cout<<"유효한 장르 번호가 아닙니다."<<endl;
        return;
    }
    if(genres[num-1])//보관한 값이 유효하면(0이 아니면)
    {
        cout<<"이미 있습니다."<<endl;
        return;
    }
    cout<<"추가할 장르명:";
    string name = ehglobal::getstr();//장르명 입력
    Genre *genre = new Genre(num,name); //장르 생성
    genres[num-1] = genre;//변경
}



void App::RemoveGenreByNum()//번호로 장르 삭제
{
    int num=0;
    cout<<"삭제할 장르 번호(1~"<<max_genres<<"):";
    num = ehglobal::getnum();
    if((num<=0)||(num>max_genres))
    {
        cout<<"유효한 장르 번호가 아닙니다."<<endl;
        return;
    }
    if(genres[num-1]==0)//보관한 값이 0이면
    {
        cout<<"없습니다."<<endl;
        return;
    }
    
    delete genres[num-1];
    genres[num-1]=0; //초기값으로 설정    
}

void App::RemoveGenreByName()//이름으로 장르 삭제
{
    string name;
    cout<<"삭제할 장르명:";
    name = ehglobal::getstr();
    EqualerByName ebname(name);

    GIter seek = find_if(genres.begin(), genres.end(), ebname);
    if(seek != genres.end())
    {
        Genre *genre = (*seek);
        int num = genre->GetNum();        
        delete genre;
        genres[num-1] = 0;
        cout<<"삭제하였습니다."<<endl;
    }
    else
    {
        cout<<"존재하지 않는 장르명입니다."<<endl;
    }
}
void App::FindGenreByNum()const //번호로 장르 검색
{
    int num=0;
    cout<<"검색할 장르 번호(1~"<<max_genres<<"):";
    num = ehglobal::getnum();
    if((num<=0)||(num>max_genres))
    {
        cout<<"유효한 장르 번호가 아닙니다."<<endl;
        return;
    }
    if(genres[num-1]==0)//보관한 값이 0이면
    {
        cout<<"없습니다."<<endl;
        return;
    }
    genres[num-1]->View();
}
void App::FindGenreByName()const //이름으로 장르 검색
{
    string name;
    cout<<"검색할 장르명:";
    name = ehglobal::getstr();
    EqualerByName ebname(name);

    GCIter seek = find_if(genres.begin(), genres.end(), ebname);
    if(seek != genres.end())
    {
        Genre *genre = (*seek);
        genre->View();
    }
    else
    {
        cout<<"존재하지 않는 장르명입니다."<<endl;
    }
}
void App::ListGenre()const //장르 목록 보기
{    
    for(int i = 0; i<max_genres; i++)
    {
        if(genres[i])
        {
            genres[i]->View();
        }
    }
}
#include "App.h"
int main()
{
    App *app = new App();
    app->Run();
    delete app;
    return 0;
}