" /> C++ 14주차 템플릿 라이브러리 | BlackWerf's Blog
포스트

C++ 14주차 템플릿 라이브러리

Map

특징

  • (‘키’, ‘값’)의 쌍을 원소로 저장하는 제네릭 컨테이너
    • 동일한 ‘키’를 가진 데이터를 중복 저장할 경우 오류 발생
  • 많은 응용에서 필요
  • 사용을 위해서는 ‘#include<map>‘ 선언 필요

함수

함수내용
insert(pair<> *element)키와 값으로 구성된 pair 객체 삽입
at(key_type& key)키에 해당하는 값 반환
begin()첫번째 pair 객체에 대한 참조 반환
end()map의 끝을 가르키는 참조 반환
empty()map이 비어있을 경우 true
find(key_type& key)키 값에 해당되는 원소를 가르키는 iterator 반환
erase(key_type& key)iterator가 가르키는 원소 삭제
size()map의 데이터 개수 반환
operator[key_size& key] ()키에 해당되는 값을 반환
operator=()이 map을 다른 map에 복사

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
    map<string, string> dic;
    dic.insert(make_pair("love", "사랑"));
    dic.insert(make_pair("apple", "사과"));

    dic["cherrry"] = "체리"; //("cherry", "체리") 저장
    cout << "사전의 단어 수 : " << dic.size() << endl;

    string eng;
    while (true)
    {
        cout << "찾고 싶은 단어 :";
        getline(cin, eng); //사용자로부터 단어 입력

        if (eng == "exit")
            break;
        if (dic.find(eng) == dic.end()) //해당 키가 존재 X할 경우
            cout << "값 존재 X" << endl;
        else
            cout << dic[eng] << endl;
    }
    cout << "종료" << endl;
}

Output

1
2
3
4
5
6
7
사전의 단어 수 : 3
찾고 싶은 단어 :apple
사과
찾고 싶은 단어 :ex
값 존재 X
찾고 싶은 단어 :exit
종료

STL 알고리즘

알고리즘 함수

  • 템플릿 함수

  • 전역함수

    • STL 컨테이너의 클래스의 멤버함수가 X
    • iterator와 함께 작동

    C++ 표준 템플릿 라이브러리

    종류함수
    계수 알고리즘count
    탐색 알고리즘search, find
    비교 알고리즘equal, mismatch
    초기화 알고리즘fill, generate
    변경 알고리즘transform
    복사 알고리즘copy
    삭제 알고리즘remove, unique
    대치 알고리즘replace
    정렬 알고리즘sort
    분할 알고리즘partition

    sort() 함수 사례

    • 2개의 매개 변수

      • 1번째 매개 변수 : 정렬을 시작한 원소의 주소

      • 2번째 매개 변수 : 정렬 범위의 마지막 원소 다음 주소

      • 3번째 매개 변수 : 오름차순, 내림차순, 사용자 정의(생략 가능)

        1
        2
        3
        4
        
        vector<string> vec;
        	...
                      
        sort(v.begin(), v.begin()+3) //v.begin() - v.begin()+2까지, 처음 3개 원소 정렬
        

    예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    int main()
    {
        //STL 알고리즘 sort()의 예제
        vector<int> v; //정수 벡터 생성
        cout << "5개의 정수 입력하세요 : ";
            for (int i = 0; i < 5; i++)
            {
                int n;
                cin >> n;
                v.push_back(n); //키보드에 읽은 정수를 벡터에 삽입
            }
            //v.begin() - v.end() 사이의 값을 오름차순으로 정렬
            //sort() 함수의 실행결과 : 벡터 v의 원소 순서 변경
            sort(v.begin(), v.end());
              
            vector<int>::iterator it; //벡터 내 원소를 탐색하는 iterator 변수 선언
            for (it = v.begin(); it != v.end(); it++)
                cout << *it << ' ';
            cout << endl;
    }
    

    Output

    1
    2
    3
    4
    5
    6
    
    5개의 정수 입력하세요 : 56
    23
    65
    75
    85
    23 56 65 75 85
    


    auto를 이용한 변수 선언

    정의

    • 컴파일러에서 변수의 타입을 추측해 자동으로 선언 함

    선언

    1
    
    auto 변수명 = 데이터값;
    
    • auto a = 1.23; //double 타입으로 선언
    • auto b = 123; //Int 타입으로 선언
    • auto c = &b; //int 주소를 저장하는 int 타입으로 선언


    • 참조형 타입으로 선언 예시

      1
      2
      3
      
      int n = 10;
      int& ref = n;
      auto d = ref; //d는 int& 타입
      
    • 리턴 타입으로 선언 예시

      1
      2
      
      int square(int x) { return x*x; }
      auto ret = square(3); //ret는 int타입
      
    • vector iterator 타입으로 선언

      1
      2
      
      for(auto iter = vec.begin(); iter != vec.end(); iter++)
          cout << *iter << endl;
      

    예시

    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
    
    int square(int x) { return x * x; }
      
    int main()
    {
        //auto 이용한 변수 선언
        auto c = 'a'; //char 타입
        auto pi = 3.14; //double 타입
        auto one = 1; //int
        auto* p = &one; //int* 타입
      
        cout << c << " " << pi << " " << one << " " << *p << endl;
      
        //함수의 리턴 타입으로 추론
        auto ret = square(3); //square()의 리턴타입이 int이므로 int
      
        cout << *p << " " << ret << endl;
      
        vector<int> vec = { 1,2,3,4,5 }; //벡터 vec에 5개 원소 1,2,3,4,5 삽입
        vector<int>::iterator iter;
        for (iter = vec.begin(); iter != vec.end(); iter++)
            cout << *iter << " "; //1 2 3 4 5 출력
        cout << endl;
      
        //템플릿에 auto를 사용해 간소화
        for (auto iter = vec.begin(); iter != vec.end(); iter++)
            cout << *iter << " "; //1 2 3 4 5 출력
    }
    

    Output

    1
    2
    3
    4
    
    a 3.14 1 1
    1 9
    1 2 3 4 5
    1 2 3 4 5
    


    Stream

    • 데이터의 흐름
    • 데이터를 전송하는 소프트웨어 모듈
    • 스트림의 양 끝에는 프로그램과 장치 연결
      • 보낸 순서대로 데이터 전달
      • 입출력 기본 단위 : Byte

    종류

    • 입력 스트림
      • 입력장치, 네트워크, 파일로부터 데이터를 프로그램으로 전달하는 스트림
    • 출력 스트림
      • 프로그램에서 출력되는 데이터를 출력장치, 네트워크, 파일로 전달하는 스트림


    입출력 스트림

    • C++ 표준에서는 스트림 방식만 지원함

    • C++ 표준에서의 스트림은 버퍼를 가짐

    • 입력 스트림의 버퍼

      • 목적 :
        1. 입력 장치로부터 입력된 데이터를 프로그램으로 전달 전, 일시 저장
        2. 키 입력 중 수정이 가능함
          • BackSpace 입력 시, 이전에 입력된 키를 버퍼에서 삭제
      • 프로그램은 사용자의 입력이 끝난 이후에 값을 읽음

        • Enter 키 : 키 입력의 끝을 의미함

          • 해당 키가 눌린 시점부터, 키 입력 버퍼에서 프로그램이 값을 읽기 시작함


        • 출력 스트림 버퍼

          • 목적
            • 프로그램에서 출력된 데이터를 출력 장치로 전송 전, 일시 저장
            • 출력 장치를 반복적으로 사용하는 비효율성 개선
          • 버퍼가 다 차거나 강제 명령 출력 시 출력 장치에 출력

    표준 입출력 스트림

    • cin : istream 타입으로, 키보드와 연결

    • cout: ostream 타입으로, 스크린과 연결

    • cerr: ostream타입으로, 스크린과 연결(스트림 버퍼 - X, Error 출력)

    • clog: ostream타입으로, 스크린과 연결(스트림 버퍼 - O, Error 출력)


    구분클래스내용
    기본 스트림ios입출력 클래스들의 기본 클래스
    스트림 클래스 공통 함수 및 상수 변수 선언
    문자 스트림istream
    ostream
    iostream
    isteam - 입력 스트림
    ostream - 출력 스트림
    iostream - 입출력 스트림
    파일 스트림ifstream
    ofstream
    fstream
    ifstream - 파일에서 데이터를 읽을 때 사용
    ofstream - 파일에 데이터를 쓸 때 사용
    fstream - 파일에서 데이터를 읽고 쓸 때 사용


    ostream

    사용방법

    1
    
    ostream& put(char ch) //ch 문자를 스트림 출력
    
    1
    
    ostream& write(char* str, int n) //str 배열의 n개 문자를 스트림 출력
    
    1
    
    ostream& flush()
    


    예시

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    int main(){
    //Hello! 출력하고 다음 줄로 이동
    cout.put('H');
    cout.put('e');
    cout.put('l');
    cout.put('l');
    cout.put('o');
    cout.put(33);
    cout.put('\n');
      
    //C++ 출력
    cout.put('C').put('+').put('+').put(' ');
      
    char str[] = "Hello World";
    cout.write(str, 5);
    }
    

    Output

    1
    2
    
    Hello!
    C++ Hello
    


    istream

    • int get()

      • 입력 스트림에서 문자를 리턴
      • 오류나 EOF(파일의 끝)는 -1 리턴

      • 예시)
    1
    2
    3
    4
    5
    
    int ch;
    while ((ch == cin.get()) != EOF) { //EOF : -1
        cout.put(ch);
        if (ch == '\n')
            break; //Enter키 입력시 읽기 중단
    
    • istream& get(char& ch)

      • 입력 스트림에서 문자를 ch에 전달
      • 오류는 내부 오류 플래그 리턴
      • 예시
      1
      2
      3
      4
      5
      6
      
      int ch;
      while (true) { //EOF : -1
          cin.get(ch); //문자 읽기
          if (cin.eof()) break; //EOF를 만날 경우 읽기를 중단
          cout.put(ch); //ch의 문자 출력
      }
      

      예시

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      
      void get1() {
          cout << "Enter키가 입력될때까지 계속 입력 및 출력됨>>";
          int ch; //EOF 비교를 위해 int
          while ((ch = cin.get()) != EOF) { //문자 읽기, EOF=-1
              cout.put(ch); //읽은 문자 출력
          
              if (ch == '\n') break; //Enter키 입력시 함수 종료
          }
      }
          void get2() {
              cout << "Enter키가 입력될때까지 계속 입력 및 출력됨>>";
              int ch; //EOF 비교를 위해 int
              while ((ch = cin.get()) != EOF) { //문자 읽기, EOF=-1
                  cout.put(ch); //읽은 문자 출력
          
                  if (ch == '\n') break; //Enter키 입력시 함수 종료
          }
      }
      

      Output

      1
      2
      3
      4
      
      Enter키가 입력될때까지 계속 입력 및 출력됨>>Test1
      Test1
      Enter키가 입력될때까지 계속 입력 및 출력됨>>Test2
      Test2
      

      get1() -> get2() 순서로 진행되며, 값을 입력 후 Enter를 입력할 경우 다음 차례로 넘어감


    문자열 입력

    • istream& get(char* s, int n)

      • 입력 스트림으로부터 n-1개의 숫자를 읽고, s에 저장
      • 마지막 글자 or \n을 만날 경우 \0을 삽입 및 종료됨
    • istream& getline(char* s, int n, char limit=’\n’)

      • 위와 비슷하지만, limit에 지정된 문자를 스트림에서 제거함


    입력 스트림 추가함수

    • istream& ignore(int n=1, int limit=EOF)

      • 입력 스트림에서 n개의 문자 제거 및, limit 문자를 만날 경우 제거 및 리턴
    • int gcount()

      • 최근 입력 스트림에서 읽은 바이트의 수를 리턴함
      • Enter키도 개수에 포함됨
    • 입력 스트림에서 문자 건너뛰기

      • 예시

        1
        2
        3
        4
        5
        
        //입력 스트림에 입력된 문자 내에서 10개 제거
        cin.ignore(10);
              
        //입력 스트림에서 10개 문자 제적 및, 제거 중 ';' 만날 경우 종료
        cin.ignore(10, ';');
        
      • 최근 읽은 ㅁ누자 개수

        1
        2
        3
        4
        5
        
        char line[80];
        cin.getline(line, 80);
              
        //getline()) 함수에서 읽은 문자의 개수를 리턴
        int n = cin.gcount(); 
        


포맷 입출력

1. 포맷 플래그

  • 입출력 스트림에서 입출력 형식을 지정하기 위한 ios 클래스의 플래그

    플래그의미
    ios::skipws0x0001입력 시, 공백문자를 무시
    ios::unitbuf0x0002출력 스트림에 들어오는 데이터를 버퍼링하지 않고, 바로 출력
    ios:uppercase0x000416진수의 A~F, 지수 표현의 E를 대문자로 출력
    ios::showcase0x000816진수이면 0x, 8진수이면 0을 숫자 앞에 붙여 출력
    ios::showpoint0x0010실수 값에 대해, 정수 부분과 더불어 소수점 이하의 끝자리들을 0으로 출력
    ios:showpos0x0020양수에 대해 + 기호 출력
    ios::left0x0040필드를 왼쪽 맞춤 형식으로 출력
    ios::right0x0080필드를 오른쪽 맞춤 형식으로 출력
    ios::internal0x0100부호를 왼쪾 맞춤으로, 숫자는 오른쪽 맞춤으로 출력
    ios::dec0x020010진수로 출력 및 디폴트로 설정
    ios::oct0x04008진수로 출력
    ios::hex0x080016진수로 출력
    ios::scientific0x1000실수에 대해 과학 산술용 규칙에 따라 출력
    ios:fixed0x2000실수에 대해 소수점 형태로 출력
    ios::boolalpha0x4000설정될 경우, true를 “true”, false를 “false”로 출력
    출력이 되지 않을 경우 , 정수 1과 0으로 출력함


    • 플래그를 세팅하는 멤버 함수

      • long setf(long flags)
        • flags를 스트림의 포맷 플래그로 설정하고 이전 플래그를 반환
      • long unsetf(long flags)
        • flags에 설정된 비트값을 스트림 포맷 플레그에서 해제 및 이전 플래그를 반환

        예시

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      
      int main()
      {
          cout << 30 << endl; //10진수 출력
          cout.unsetf(ios::dec); //10진수 해제
          cout.setf(ios::hex); //16진수로 설정
          cout << 30 << endl;
          
          cout.setf(ios::showbase); //16진수로 설정
          cout << 30 << endl;
          
          cout.setf(ios::uppercase); //16진수의 A~F는 대문자로 출력
          cout << 30 << endl;
          
          cout.setf(ios::dec | ios::showpoint); //10진수 표현과 동시에 소수점 이하 나머지는 0으로 출력
          
          cout << 23.5 << endl;
          
          cout.setf(ios::scientific); //실수를 과학산술용 표현으로 출력
          cout << 23.5 << endl;
          
          cout.setf(ios::showpos); //양수인 경우 + 부호도 함께 출력
          cout << 23.5;
      }
      

      Output

      1
      2
      3
      4
      5
      6
      7
      
      30
      1e
      0x1e
      0X1E
      23.5000
      2.350000E+01
      +2.350000E+01
      

2. 포맷 함수

정의

  • 포맷을 변경하는 함수

종류

  • int width(int minWidth)

    • 출력되는 필드의 최소 너비를 minWidth로 설정 및 이전 설정을 반환
  • char fill(char cFill)

    • 필드의 빈칸을 cFill 문자로 채우고, 이전 설정을 반환
  • int precision(int np)

    • 출력되는 수의 유효 숫자 자리 수를 np개로 설정(소수점은 제외)

    예시

    1
    
    1
    


3. 조작자

  • manipulator, 스트림 조작
  • 조작자 : 함수
    • C++ 표준 라이브러리에 구현된 조작자로 입출력 포맷의 지정이 목적임
    • 다양한 목적으로 자신만의 조작자를 작성이 가능함
    • 매개 변수가 없는 조작자 / 매개 변수를 보유한 조작자로 분류 가능
  • 조작자는 항상 «나» 연산자와 함께 사용됨
  • 매개변수를 가진 조작자는 **#include ** 필요


  • 매개변수가 없는 조작자

    1
    2
    
    cout << hex << showbase << 30 << endl;
    cout << dec << showpos << 100 << endl;
    

    Output

    1
    2
    
    0x1e
    +100
    
  • 매개변수가 있는 조작자

    1
    
    cout << setw(10) << setfill('^') << "Test" << endl;
    

    Output

    1
    
    ^^^^^^Test
    


    예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    int main()
    {
        cout << showbase;
      
        //타이틀 출력
        cout << setw(8) << "Number";
        cout << setw(10) << "Octal";
        cout << setw(10) << "Hexa" << endl;
      
        //하나의 수를 10, 8, 16진수 형태로 한줄에 출력
        for (int i = 0; i < 50; i += 5) {
            cout << setw(8) << setfill('.') << dec << i; //10진수
            cout << setw(10) << setfill('.') << oct << i; //8진수
            cout << setw(10) << setfill('.') << hex << i << endl; //16진수
    

    Output

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      Number     Octal      Hexa
    .......0.........0.........0
    .......5........05.......0x5
    ......10.......012.......0xa
    ......15.......017.......0xf
    ......20.......024......0x14
    ......25.......031......0x19
    ......30.......036......0x1e
    ......35.......043......0x23
    ......40.......050......0x28
    ......45.......055......0x2d
    


삽입 연산자와 추출 연산자

삽입 연산자

  • « 연산자는 C++의 기본 연산자로 정수 시프트의 연산자
  • ostream 클래스에 중복으로 작성되어 있음

추출 연산자

  • ’»’ 연산자는 C++의 기본 연산자로, 삽입 연산자와 같이 정수 시프트의 연산장임
  • ostream 클래스에 중복으로 작성되어 있음

14-1부터

파일 쓰기

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
int main()
{
    //파일 출력 예제
    char name[10], dept[20];
    int sid;
    //키보드로부터 읽기
    cout << " 이름 : ";
    cin >> name; //키보드에서 이름 입력 받음
    cout << " 학번 : ";
    cin >> sid; 
    cout << " 학과 : ";
    cin >> dept;

    //파일 열기 및 출력 스트림 생성
    ofstream fd("D:\\23-2\\CPP\\test.txt");
    if (!fd) { //열기 실패 검사
        cout << "파일을 열수 없습니다.";
        return 0;
    }
    //파일 쓰기
    fd << name << endl; //name 쓰기
    fd << sid << endl << endl;
    fd << dept << endl;
    cout << "파일 쓰기 성공" << endl;
    fd.close(); //파일 닫기
}

Output

1
2
3
4
 이름 : ABC
 학번 : 20211111
 학과 : Computer Engineering
파일 쓰기 성공

Image Alt 텍스트

파일 모드

파일 모드 설정

파일 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
    //파일의 연결
    const char* firstFile = "D:\\23-2\\CPP\\test_write2.txt";
    const char* secondFile = "C:\\Windows\\system.ini";
    
    fstream fout(firstFile, ios::out | ios::app); //쓰기 모드로 파일 열기
        if (!fout) {
            cout << firstFile << "열기 오류";
            return 0;
        }

        fstream fin(secondFile, ios::in); //읽기 모드로 파일 열기
        if (!fin) {
            cout << secondFile << "열기 오류";
            return 0;
        }
        int c;
        while ((c = fin.get()) != EOF)  //파일 끝까지 문자 읽기
            fout.put(c); // 읽은 문자 기록

        fin.close(); //입력 파일 닫기
        fout.close(); //출력 파일 닫기
}

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
; for 16-bit app support
[386Enh]
woafont=dosapp.fon
EGA80WOA.FON=EGA80WOA.FON
EGA40WOA.FON=EGA40WOA.FON
CGA80WOA.FON=CGA80WOA.FON
CGA40WOA.FON=CGA40WOA.FON

[drivers]
wave=mmdrv.dll
timer=timer.drv

[mci]

예외처리

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
int main()
{
    //예외 처리
    int n, sum, average;
    while (true)
    {
        cout << "합을 입력하세요 : ";
        cin >> sum;
        cout << "인원수를 입력하세요 : ";
        cin >> n;

        try {
            if (n <= 0) //오류 탐지
                throw n; //catch(int x) 블록으로 점프
            else
                average = sum / n;
        }
        catch (int x) {
            cout << "예외 발생 " << x << "으로 나눌 수 없음" << endl;
            average = 0;
            cout << endl;
            continue;
        }
        cout << "평균 : " << average << endl << endl; //평균 출력
    }
}

Output

1
2
3
4
5
6
7
합을 입력하세요 : 4
인원수를 입력하세요 : -4
예외 발생 -4으로 나눌 수 없음

합을 입력하세요 : 20
인원수를 입력하세요 : 4
평균 : 5
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.