C++/Library 2021. 3. 30. 00:06

forward

  • <utility> 라이브러리

예제

간단

  • forward를 사용하지 않았을 경우

    #include <iostream>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T t)
    {
        func(t);
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by L-ref
    */
  • func_wrapper의 파라미터를 T &&으로 받아도 결과는 같다.

    • 파라미터를 R-value로 받더라도 t 자체가 변수이기 때문에 L-value로 인식하는 것 같다.
    #include <iostream>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T&& t)
    {
        func(t);
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by L-ref
    */
  • R-ref를 제대로 전달하고 싶으면, 다음과 같이 forward를 사용하면 된다.

    #include <iostream>
    #include <vector>
    #include <utility>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T&& t)
    {
        func(std::forward<T>(t));
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by R-ref
    */

컨테이너 예제

  • std::move의 경우 명확한 의도를 보여주기 위해서 사용하기도 한다.

    #include <iostream>
    #include <utility>
    
    class CustomVector
    {
        unsigned    n_data_ = 0;
        int*        ptr_ = nullptr;
    
    public:
        CustomVector(const unsigned& n_data, const int& init_in = 0)
        {
            std::cout << "Constructor\n";
            init(n_data, init_in);
        }
    
        CustomVector(CustomVector& l_input)
        {
            std::cout << "Copy Constructor\n";
    
            init(l_input.n_data_);
    
            for (unsigned i = 0; i < n_data_; ++i)
                ptr_[i] = l_input.ptr_[i];
        }
    
        CustomVector(CustomVector&& r_input)
        {
            std::cout << "Move Constructor\n";
    
            n_data_ = r_input.n_data_;
            ptr_ = r_input.ptr_;
    
            r_input.n_data_ = 0;
            r_input.ptr_ = nullptr;
        }
    
        ~CustomVector()
        {
            delete[] ptr_;
        }
    
        void    init(const unsigned& n_data, const int& init_in = 0)
        {
            n_data_ = n_data;
            ptr_ = new int[n_data_];
            for (unsigned i = 0; i < n_data_; ++i)
                ptr_[i] = init_in;
        }
    };
    
    void    doSomething(CustomVector& vec)
    {
        std::cout << "Pass by L-reference\n";
        CustomVector new_vec(vec);
    }
    
    void    doSomething(CustomVector&& vec)
    {
        std::cout << "Pass by R-reference\n";
        CustomVector new_vec(std::move(vec));  // 명확한 의도를 보여주기 위해 move 사용
        //CustomVector new_vec(vec);
    }
    
    template <typename T>
    void    doSomethingTemplate(T&& vec)
    {
        doSomething(std::forward<T>(vec));
    }
    
    int        main()
    {
        using namespace std;
    
        CustomVector    my_vec(10, 1024);
    
        doSomethingTemplate(my_vec);
        doSomethingTemplate(CustomVector(10, 123));
    }
    
    /* stdout
    Constructor
    Pass by L-reference
    Copy Constructor
    Constructor
    Pass by R-reference
    Move Constructor
    */

'C++ > Library' 카테고리의 다른 글

C++ future  (0) 2021.03.30
C++ 멀티쓰레딩 (Multithreading)  (0) 2021.03.30
C++ atomic  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++/Library 2021. 3. 30. 00:05

future

  • <future> 라이브러리

  • <future> 라이브러리에 <thread> 라이브러리가 포함되어 있다.

    <future>

    #include <chrono>
    #include <condition_variable>
    #include <functional>
    #include <memory>
    #include <mutex>
    #include <ppltasks.h>
    #include <system_error>
    #include <thread>
    #include <utility>

예제

  • 쓰레드 예제와 이를 future, async로 적용한 예제

    #include <iostream>
    #include <future>
    
    int         main()
    {
        using namespace std;
    
        {
            int result;
    
            thread t([&] { result = 1 + 2; });
            t.join();
            cout << result << endl;
        }
    
        {
            auto fut = std::async([] { return 1 + 2; });
    
            cout << fut.get() << endl;
        }
    }
    
    /* stdout stderr
    3
    3
    */
  • thread를 통해 future를 사용하려면 promise가 필요하다.

    • promise.set_value()가 호출되면 promise 객체가 자신의 future 객체에게 값을 전달하고, future.get() 함수를 통해 기다렸다가 값을 받을 수 있다. (내부적으로 wait 함수가 기다린다.)

      #include <iostream>
      #include <future>
      
      int         main()
      {
          using namespace std;
      
          std::promise<int> prom;
          auto fut = prom.get_future();
      
          auto t = thread([](std::promise<int>&& prom)
              {
                  prom.set_value(1 + 2);
              }, std::move(prom));
      
          cout << fut.get() << endl;
          t.join();
      }
      
      /* stdout stderr
      3
      */
  • asyncthread는 처리하는 방식이 다르다..는데

    • 강의에서는 출력되는 순서가 다른데, 내 컴퓨터에서는 똑같다.

      #include <iostream>
      #include <future>
      
      int         main()
      {
          using namespace std;
      
          auto f1 = std::async([] {
              cout << "async1 start\n";
              this_thread::sleep_for(chrono::seconds(2));
              cout << "async1 end\n";
              });
      
          auto f2 = std::async([] {
              cout << "async2 start\n";
              this_thread::sleep_for(chrono::seconds(1));
              cout << "async2 end\n";
              });
      
          cout << "Main function\n";
      }
      
      /* stdout stderr
      Main function
      async1 start
      async2 start
      async2 end
      async1 end
      */
      #include <iostream>
      #include <future>
      
      int         main()
      {
          using namespace std;
      
          auto f1 = std::thread([] {
              cout << "thread1 start" << endl;
              this_thread::sleep_for(chrono::seconds(2));
              cout << "thread1 end" << endl;
              });
      
          auto f2 = std::thread([] {
              cout << "thread2 start" << endl;
              this_thread::sleep_for(chrono::seconds(1));
              cout << "thread2 end" << endl;
              });
      
          cout << "Main function" << endl;
          f1.join();
          f2.join();
      }
      
      /* stdout stderr
      Main function
      thread1 start
      thread2 start
      thread2 end
      thread1 end
      */
  • async는 반환 값을 받는 변수가 없으면 멀티 쓰레딩 기능이 작동하지 않는다.

    #include <iostream>
    #include <future>
    
    int         main()
    {
        using namespace std;
    
        std::async([] {
            cout << "async1 start" << endl;
            this_thread::sleep_for(chrono::seconds(2));
            cout << "async1 end" << endl;
            });
    
        std::async([] {
            cout << "async2 start" << endl;
            this_thread::sleep_for(chrono::seconds(1));
            cout << "async2 end" << endl;
            });
    
        cout << "Main function" << endl;
    }
    
    /* stdout stderr
    async1 start
    async1 end
    async2 start
    async2 end
    Main function
    */

'C++ > Library' 카테고리의 다른 글

C++ forward  (0) 2021.03.30
C++ 멀티쓰레딩 (Multithreading)  (0) 2021.03.30
C++ atomic  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++/Library 2021. 3. 30. 00:03

멀티쓰레딩 (Multithreading)

  • <thread> 라이브러리

  • 병렬 프로그래밍을 위한 라이브러리이다.

  • 쓰레드를 생성하여 다른 코어에서 작업할 수 있도록 한다.


예제

  • CPU 사용률 100% 찍어보기

    • 출력이 섞여서 나오는 현상(레이스 컨디션)이 발생한다. 이는 mutexatomic, 세마포어 등으로 해결할 수 있다.
    #include <iostream>
    #include <string>
    #include <thread>
    #include <vector>
    
    int         main()
    {
        using namespace std;
    
        const int num_logical_processors = std::thread::hardware_concurrency();
    
        cout << "Number of processors : " << num_logical_processors << endl;
        cout << "ID of this thread : " << std::this_thread::get_id() << endl;
    
        vector<thread>  threads;
        threads.resize(num_logical_processors);
    
        for (auto& e : threads)
            e = thread([]() {
            cout << std::this_thread::get_id() << endl;
            while (true) {}});
    
        for (auto& e : threads)
            e.join();
    }
    
    /* stdout stderr
    Number of processors : 12
    ID of this thread : 16588
    13524
    14792
    17928
    18368
    17452
    14392
    19440
    12996
    16180
    1773614800
    18504
    */

'C++ > Library' 카테고리의 다른 글

C++ forward  (0) 2021.03.30
C++ future  (0) 2021.03.30
C++ atomic  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++/Library 2021. 3. 30. 00:03

atomic

  • <atomic> 라이브러리

  • 보장하고 싶은 변수를 atomic<type> 형식으로 정의하면 된다.

  • 성능이 느려진다.

    • 성능을 위해 mutex를 사용하는 것 같다.

예제

  • atomic을 사용하지 않은 예제

    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int         main()
    {
        using namespace std;
    
        int shared_memory(0);
    
        auto count_func = [&]() {
            for (int i = 0; i < 1000; ++i)
            {
                this_thread::sleep_for(chrono::milliseconds(1));
                shared_memory++;
            }
        };
    
        thread t1 = thread(count_func);
        thread t2 = thread(count_func);
    
        t1.join();
        t2.join();
    
        cout << "Value is " << shared_memory << endl;
    }
    
    /* stdout stderr
    Value is 1997
    */
    • 값이 2000이 아닌 1997이 나온 것을 볼 수 있다.
  • atomic을 사용한 예제

    • <atomic> 라이브러리를 포함하지 않아도 사용할 수 있었다.

    • 여기서 shared_memory++atomic 클래스에서 오버로딩한 연산자를 사용한다.

    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <atomic>
    
    int         main()
    {
        using namespace std;
    
        atomic<int> shared_memory(0);
    
        auto count_func = [&]() {
            for (int i = 0; i < 1000; ++i)
            {
                this_thread::sleep_for(chrono::milliseconds(1));
                shared_memory++;
            }
        };
    
        thread t1 = thread(count_func);
        thread t2 = thread(count_func);
    
        t1.join();
        t2.join();
    
        cout << "Value is " << shared_memory << endl;
    }
    
    /* stdout stderr
    Value is 2000
    */

'C++ > Library' 카테고리의 다른 글

C++ future  (0) 2021.03.30
C++ 멀티쓰레딩 (Multithreading)  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++ fstream  (0) 2021.03.29
C++/Library 2021. 3. 30. 00:03

mutex

  • <mutex> 라이브러리

  • Mutual Exclusion의 약자이다.


예제

  • mutex를 적용하지 않은 예제

    • 출력이 섞여서 나오는 것을 볼 수 있다.
    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int         main()
    {
        using namespace std;
    
        const int num_logical_processors = std::thread::hardware_concurrency();
    
        cout << "Number of processors : " << num_logical_processors << endl;
        cout << "ID of this thread : " << std::this_thread::get_id() << endl;
    
        auto work_func = [](const string& name)
        {
            for (int i = 0; i < 5; ++i)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                cout << name << ' ' << std::this_thread::get_id() << " is working " << i << endl;
            }
        };
    
        std::thread t1 = std::thread(work_func, "Jack Jack");
        std::thread t2 = std::thread(work_func, "Dash");
    
        t1.join();
        t2.join();
    }
    
    /* stdout stderr
    Number of processors : 12
    ID of this thread : 16040
    Jack Jack 5336 is working 0
    Dash 8368 is working 0
    Jack Jack 5336 is working 1Dash 8368 is working 1
    
    Dash 8368 is working 2
    Jack Jack 5336 is working 2
    Dash 8368 is working 3
    Jack Jack 5336 is working 3
    Jack Jack 5336 is working 4
    Dash 8368 is working 4
    */

  • mutex를 사용한 예제

    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <mutex>
    
    int         main()
    {
        using namespace std;
    
        mutex mtx;
    
        const int num_logical_processors = std::thread::hardware_concurrency();
    
        cout << "Number of processors : " << num_logical_processors << endl;
        cout << "ID of this thread : " << std::this_thread::get_id() << endl;
    
        auto work_func = [&](const string& name)
        {
            for (int i = 0; i < 5; ++i)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
                mtx.lock();
                cout << name << ' ' << std::this_thread::get_id() << " is working " << i << endl;
                mtx.unlock();
            }
        };
    
        std::thread t1 = std::thread(work_func, "Jack Jack");
        std::thread t2 = std::thread(work_func, "Dash");
    
        t1.join();
        t2.join();
    }
    
    /* stdout stderr
    Number of processors : 12
    ID of this thread : 1588
    Jack Jack 17596 is working 0
    Dash 14068 is working 0
    Jack Jack 17596 is working 1
    Dash 14068 is working 1
    Dash 14068 is working 2
    Jack Jack 17596 is working 2
    Jack Jack 17596 is working 3
    Dash 14068 is working 3
    Dash 14068 is working 4
    Jack Jack 17596 is working 4
    */
    • 만약 mutex.unlock()을 하지 않으면 다른 쓰레드에서 해당 자원을 사용할 수 없다.

C++11

lock_guard

  • mutex.lock(), mutex.unlock()을 사용하지 않고, 정의하면 락이 걸리고 영역을 벗어나면 언락을 해주는 클래스이다.

  • C++17부터는 템플릿타입 자리에 아무것도 안넣어도 된다. (lock_guard lock(mtx) 이런 식으로)

    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <mutex>
    
    int         main()
    {
        using namespace std;
    
        int shared_memory(0);
        mutex mtx;
    
        auto count_func = [&]() {
            for (int i = 0; i < 1000; ++i)
            {
                this_thread::sleep_for(chrono::milliseconds(1));
    
                lock_guard<mutex> lock(mtx);
    
                shared_memory++;
            }
        };
    
        thread t1 = thread(count_func);
        thread t2 = thread(count_func);
    
        t1.join();
        t2.join();
    
        cout << "Value is " << shared_memory << endl;
    }
    
    /* stdout stderr
    Value is 2000
    */

C++17

scoped_lock

  • 뮤텍스 락을 자주 걸면 오버헤드가 커지므로 성능 저하가 발생한다.

  • lock_guard에서 여러 mutex를 한번에 lock할 수 있는 기능을 추가한 클래스라고 한다. 즉 상위 호환이다.

    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <mutex>
    
    int         main()
    {
        using namespace std;
    
        int shared_memory(0);
        mutex mtx;
    
        auto count_func = [&]() {
            for (int i = 0; i < 1000; ++i)
            {
                this_thread::sleep_for(chrono::milliseconds(1));
    
                scoped_lock<mutex> lock(mtx);
    
                shared_memory++;
            }
        };
    
        thread t1 = thread(count_func);
        thread t2 = thread(count_func);
    
        t1.join();
        t2.join();
    
        cout << "Value is " << shared_memory << endl;
    }
    
    /* stdout stderr
    Value is 2000
    */

'C++ > Library' 카테고리의 다른 글

C++ 멀티쓰레딩 (Multithreading)  (0) 2021.03.30
C++ atomic  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++ fstream  (0) 2021.03.29
C++ 정규 표현식 (Regular Expressions)  (0) 2021.03.29
C++/Library 2021. 3. 29. 23:59

파일 임의 위치 접근

  • <fstream> 라이브러리

예제

  • ifs.seekg() 함수는 첫 번째 인자(Offset)를 받아서 그만큼 이동한다.

    • 두 번째 인자로 ios::cur(current)를 주면, 현재의 위치를 기준으로 오프셋만큼 이동한다.

      • 이외에도 ios::beg(begin), ios::end를 넣을 수 있다.
  • ifs.get() 함수는 커서 위치에서 1바이트를 읽고 반환한다.

    • 위치는 1바이트 뒤로 이동된다.
  • ifs.tellg() 함수는 현재 위치를 반환한다.

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    int         main()
    {
        using namespace std;
    
        const string filename = "my_file.txt";
    
        {
            ofstream ofs(filename);
    
            // abcdefghijklmnopqrstuvwxyz
            for (char i = 'a'; i <= 'z'; ++i)
                ofs << i;
            ofs << endl;
        }
        {
            ifstream ifs(filename);
    
            ifs.seekg(5);
            cout << (char)ifs.get() << endl;
    
            ifs.seekg(5, ios::cur);
            cout << (char)ifs.get() << endl;
    
            string str;
            getline(ifs, str);
            cout << str << endl;
    
            ifs.seekg(0, ios::beg);
            cout << ifs.tellg() << endl;
    
            ifs.seekg(0, ios::end);
            cout << ifs.tellg() << endl;
        }
    }
    
    /* stdout stderr
    f
    l
    mnopqrstuvwxyz
    0
    28
    */

  • 파일 하나에 입출력을 같이 할 때는 fstream 클래스를 사용하면 된다.

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    int         main()
    {
        using namespace std;
    
        const string filename = "my_file.txt";
    
        //fstream iofs(filename, ios::in | ios::out);
        fstream iofs(filename);
    
        iofs.seekg(5);
        cout << (char)iofs.get() << endl;
    
        iofs.seekg(5);
        iofs.put('A');
    }
    
    /* stdout stderr
    f
    */
    
    /* my_file.txt
    abcdeAghijklmnopqrstuvwxyz
    
    */

'C++ > Library' 카테고리의 다른 글

C++ atomic  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ fstream  (0) 2021.03.29
C++ 정규 표현식 (Regular Expressions)  (0) 2021.03.29
C++ 흐름 상태 (Stream States)  (0) 2021.03.29
C++/Library 2021. 3. 29. 23:59

fstream

  • <fstream> 라이브러리

  • 기본 옵션은 ASCII 포맷으로 덮어쓰기이다.

    • 옵션에 대한 플래그는 다음과 같다.

      xiosbase

      static constexpr _Openmode in         = static_cast<_Openmode>(0x01);
      static constexpr _Openmode out        = static_cast<_Openmode>(0x02);
      static constexpr _Openmode ate        = static_cast<_Openmode>(0x04);
      static constexpr _Openmode app        = static_cast<_Openmode>(0x08);
      static constexpr _Openmode trunc      = static_cast<_Openmode>(0x10);
      static constexpr _Openmode _Nocreate  = static_cast<_Openmode>(0x40);
      static constexpr _Openmode _Noreplace = static_cast<_Openmode>(0x80);
      static constexpr _Openmode binary     = static_cast<_Openmode>(0x20);
  • 옵션으로 이어쓰기, binary 포맷으로 열기가 가능하다.

  • 클래스의 소멸자에서 파일을 닫아주기 때문에 굳이 fstream.close()를 할 필요가 없다. (RAII)

    • 하지만 가독성 등의 이유로 명시하는게 낫다고 생각한다.
  • 비주얼 스튜디오에서 Ctrl + K를 누르고 R을 누르면(컨트롤 없이) 작업 중인 폴더가 익스플로러로 열린다.


예제

  • ASCII 포맷으로 저장 후 불러오는 예제

    #include <iostream>
    #include <string>
    #include <fstream>
    
    int         main()
    {
        using namespace std;
    
        string filename = "my_first_file.txt";
    
        {
            ofstream ofs(filename);
    
            if (!ofs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            ofs << "Line 1\n";
            ofs << "Line 2\n";
    
            ofs.close();
        }
    
        {
            ifstream ifs(filename);
    
            if (!ifs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            while (ifs)
            {
                string str;
                getline(ifs, str);
                cout << str << endl;
            }
    
            ifs.close();
        }
    }
    
    /* stdout stderr
    Line 1
    Line 2
    */

  • ios::app 사용

    #include <iostream>
    #include <string>
    #include <fstream>
    
    int         main()
    {
        using namespace std;
    
        string filename = "my_first_file.txt";
    
        {
            ofstream ofs(filename, ios::app);
    
            if (!ofs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            ofs << "Line 1\n";
            ofs << "Line 2\n";
    
            ofs.close();
        }
    
        {
            ifstream ifs(filename);
    
            if (!ifs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            while (ifs)
            {
                string str;
                getline(ifs, str);
                cout << str << endl;
            }
    
            ifs.close();
        }
    }
    
    /* stdout stderr (3번 반복 실행 시)
    Line 1
    Line 2
    Line 1
    Line 2
    Line 1
    Line 2
    */

  • binary 포맷 예제

    #include <iostream>
    #include <string>
    #include <fstream>
    
    int         main()
    {
        using namespace std;
    
        string filename = "my_first_file.txt";
    
        {
            ofstream ofs(filename, ios::binary);
    
            if (!ofs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            const unsigned num_data = 10;
            ofs.write((char*)&num_data, sizeof(num_data));
            for (int i = 0; i < num_data; ++i)
                ofs.write((char*)&i, sizeof(i));
    
            ofs.close();
        }
    
        {
            ifstream ifs(filename, ios::binary);
    
            if (!ifs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            unsigned num_data = 0;
            ifs.read((char*)&num_data, sizeof(num_data));
            cout << "Number of data : " << num_data << endl;
            for (unsigned i = 0; i < num_data; ++i)
            {
                int num;
                ifs.read((char*)&num, sizeof(num));
                cout << num << endl;
            }
    
            ifs.close();
        }
    }
    
    /* stdout stderr
    Number of data : 10
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    */

  • stringstream 사용

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    int         main()
    {
        using namespace std;
    
        string filename = "my_first_file.txt";
    
        {
            ofstream ofs(filename, ios::binary);
    
            if (!ofs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            stringstream ss;
            ss << "Line 1\n";
            ss << "Line 2\n";
            string str = ss.str();
    
            unsigned str_length = str.size();
            ofs.write((char*)&str_length, sizeof(str_length));
            ofs.write(str.c_str(), str_length);
    
            ofs.close();
        }
    
        {
            ifstream ifs(filename, ios::binary);
    
            if (!ifs)
            {
                cerr << "Fail to open file\n";
                exit(1);
            }
    
            unsigned str_length = 0;
            ifs.read((char*)&str_length, sizeof(str_length));
            cout << "Size of string: " << str_length << endl;
            string str;
            str.resize(str_length);
            ifs.read(&str[0], str_length);
            cout << str << endl;
    
            ifs.close();
        }
    }
    
    /* stdout stderr
    Size of string: 14
    Line 1
    Line 2
    */

'C++ > Library' 카테고리의 다른 글

C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29
C++ 정규 표현식 (Regular Expressions)  (0) 2021.03.29
C++ 흐름 상태 (Stream States)  (0) 2021.03.29
C++ cout  (0) 2021.03.29
C++/Library 2021. 3. 29. 23:58

정규 표현식 (Regular Expressions)

기본 예제

#include <iostream>
#include <regex>

int         main()
{
    using namespace std;

    regex   re("\\d");
    //regex   re("[ab]");
    //regex   re("[[:digit:]]{3}");
    //regex   re("[A-Z]+");
    //regex   re("[A-Z]{3}");
    //regex   re("[A-Z]{1, 5}");
    //regex   re("([0-9]{1})([-]?)([0-9]{1,4})");
    //regex   re("([0]{1}[1]{1}[0-9]{1})([-]?)([0-9]{3,4})([-]?)([0-9]{4})");
    //regex   re("([[:digit:][:alpha:]]+)([@]{1})([[:digit:][:alpha:]]+)([.]{1})([[:alpha:]]+)");

    string  str;

    while (true)
    {
        getline(cin, str);

        if (std::regex_match(str, re))
            cout << "Match\n";
        else
            cout << "No match\n";

        auto begin = std::sregex_iterator(str.begin(), str.end(), re);
        auto end = std::sregex_iterator();
        for (auto itr = begin; itr != end; ++itr)
        {
            std::smatch match = *itr;
            cout << match.str() << ' ';
        }
        cout << endl;
    }
}

/* stdin
1
2
123
*/

/* stdout stderr
Match
1
Match
2
No match
1 2 3
*/

'C++ > Library' 카테고리의 다른 글

C++ 파일 임의 위치 접근  (0) 2021.03.29
C++ fstream  (0) 2021.03.29
C++ 흐름 상태 (Stream States)  (0) 2021.03.29
C++ cout  (0) 2021.03.29
C++ ostream  (0) 2021.03.29
C++/Library 2021. 3. 29. 23:57

흐름 상태 (Stream States)

흐름 상태 출력 예제

  • 오류 상태 플래그를 통해 입력이 잘 들어갔는지에 대한 결과를 확인할 수 있다.

    #include <iostream>
    #include <cctype>
    #include <string>
    #include <bitset>
    
    void        printCharacterClassification(const int& i)
    {
        using namespace std;
    
        cout << boolalpha;
        cout << "isalnum : " << bool(std::isalnum(i)) << endl;
        cout << "isblank : " << bool(std::isblank(i)) << endl;
        cout << "isdigit : " << bool(std::isdigit(i)) << endl;
        cout << "islower : " << bool(std::islower(i)) << endl;
        cout << "isupper : " << bool(std::isupper(i)) << endl;
    }
    
    void        printStates(const std::ios& stream)
    {
        using namespace std;
    
        cout << boolalpha;
        cout << "good() : " << stream.good() << endl;
        cout << "eof() : " << stream.eof() << endl;
        cout << "fail() : " << stream.fail() << endl;
        cout << "bad() : " << stream.bad() << endl;
    }
    
    int         main()
    {
        using namespace std;
    
        while (true)
        {
            char i;
            cin >> i;
    
            printStates(cin);
            printCharacterClassification(i);
    
            cin.clear();
            cin.ignore(1024, '\n');
            cout << endl;
        }
    }
    
    /* stdin
    a
    A
    1024
    */
    
    /* stdout stderr
    good() : true
    eof() : false
    fail() : false
    bad() : false
    isalnum : true
    isblank : false
    isdigit : false
    islower : true
    isupper : false
    
    good() : true
    eof() : false
    fail() : false
    bad() : false
    isalnum : true
    isblank : false
    isdigit : false
    islower : false
    isupper : true
    
    good() : true
    eof() : false
    fail() : false
    bad() : false
    isalnum : true
    isblank : false
    isdigit : true
    islower : false
    isupper : false
    */
    • 위의 경우 cin의 특성때문에 isblank() 함수는 없는 것과 같다.

    • 공백도 확인하려면 다음과 같은 방식이 필요하다.

      #include <iostream>
      #include <cctype>
      #include <string>
      #include <bitset>
      
      bool        isAllDigit(const std::string& str)
      {
          for (auto& e : str)
              if (!std::isdigit(e))
                  return (false);
          return true;
      }
      
      void        classifyCharacters(const std::string& str)
      {
          using namespace std;
      
          for (auto& e : str)
          {
              cout << e << endl;
              cout << "\tisdigit : " << isdigit(e) << endl;
              cout << "\tisblank : " << isblank(e) << endl;
              cout << "\tisalpha : " << isalpha(e) << endl;
          }
      }
      
      int         main()
      {
          using namespace std;
      
          cout << boolalpha;
          classifyCharacters("1234");
          cout << isAllDigit("1234") << endl;
          classifyCharacters("a 1234");
          cout << isAllDigit("a 1234") << endl;
      }
      
      /* stdout stderr
      1
              isdigit : 4
              isblank : 0
              isalpha : 0
      2
              isdigit : 4
              isblank : 0
              isalpha : 0
      3
              isdigit : 4
              isblank : 0
              isalpha : 0
      4
              isdigit : 4
              isblank : 0
              isalpha : 0
      true
      a
              isdigit : 0
              isblank : 0
              isalpha : 2
      
              isdigit : 0
              isblank : 64
              isalpha : 0
      1
              isdigit : 4
              isblank : 0
              isalpha : 0
      2
              isdigit : 4
              isblank : 0
              isalpha : 0
      3
              isdigit : 4
              isblank : 0
              isalpha : 0
      4
              isdigit : 4
              isblank : 0
              isalpha : 0
      false
      */

_Iosb

<xiosbase>

  static constexpr _Iostate goodbit = static_cast<_Iostate>(0x0);
  static constexpr _Iostate eofbit  = static_cast<_Iostate>(0x1);
  static constexpr _Iostate failbit = static_cast<_Iostate>(0x2);
  static constexpr _Iostate badbit  = static_cast<_Iostate>(0x4);
flag meaning
goodbit 오류가 없다
eofbit 스트림으로부터 추출 작업(extracting operation) 진행 중 EOF에 도달
failbit 마지막 입력 작업이 자체 내부 오류 때문에 실패
badbit 스트림 버퍼의 입출력 작업이 실패

ios_base

  • ios::fail()

    • failbitbadbit가 설정되어있으면 true 반환

    • operator!fail()을 호출한다.

  • ios::clear()

    • 오류 상태 플래그를 새로운 값으로 설정

      • 기본 값은 goodbit : 오류 상태 플래그를 0으로 초기화 시킨다.
  • ios::rdstate()

    • 오류 상태 플래그(error state flag)를 반환한다.

      • 위의 비트들과 AND 연산으로 플래그를 확인할 수 있다.

      • AND 연산은 귀찮으므로 그냥 ios::eof(), ios::fail(), ios::bad(), ios::good() 함수를 사용하자.

basic_ios

  • clear(), setstate() 함수의 기본 값 설정

'C++ > Library' 카테고리의 다른 글

C++ fstream  (0) 2021.03.29
C++ 정규 표현식 (Regular Expressions)  (0) 2021.03.29
C++ cout  (0) 2021.03.29
C++ ostream  (0) 2021.03.29
C++ istream  (0) 2021.03.29
C++/Library 2021. 3. 29. 23:56

cout

  • <iostream> 라이브러리

출력 형식 설정

  • 여러가지 방법으로 출력 형식을 설정할 수 있다.

  • +부호 붙이기, 16진수 출력, 대문자 출력

    #include <iostream>
    
    int         main()
    {
        using namespace std;
    
        cout.setf(std::ios::showpos);
        cout << 108 << endl;
    
        cout.unsetf(std::ios::showpos);
        cout << 108 << endl;
    
        cout.unsetf(std::ios::dec);
        cout.setf(std::ios::hex);
        cout << 108 << endl;
    
        cout.setf(std::ios::hex, std::ios::basefield);
        cout << 108 << endl;
    
        cout << std::dec;
        cout << 108 << endl;
    
        cout.setf(std::ios::uppercase);
        cout << std::hex;
        cout << 108 << endl;
    
        cout << std::nouppercase;
        cout << 108 << endl;
    
        cout << boolalpha << true << ' ' << false << endl;
        cout << noboolalpha << true << ' ' << false << endl;
    }
    
    

/* stdout stderr
+108
108
6c
6c
108
6C
6c
true false
1 0
*/


## `<iomanip>`

- `<iomanip>` 라이브러리를 포함하면 더 유연하게 출력 형식을 조절할 수 있다.

- 소수점 자릿수 조절, 과학적 표기법, 소수점 표시

  ```c++
  #include <iostream>
  #include <iomanip>

  void        printFloat()
  {
      using namespace std;

      cout << std::setprecision(3) << 123.456 << endl;
      cout << std::setprecision(4) << 123.456 << endl;
      cout << std::setprecision(5) << 123.456 << endl;
      cout << std::setprecision(6) << 123.456 << endl;
      cout << std::setprecision(7) << 123.456 << endl;
      cout << endl;
  }

  int         main()
  {
      using namespace std;

      printFloat();

      cout << std::fixed;
      printFloat();

      cout << std::scientific << std::uppercase;
      cout << "this is lowercase\n";
      printFloat();

      cout << std::defaultfloat;
      cout << std::showpoint;
      printFloat();
  }


  /* stdout stderr
  123
  123.5
  123.46
  123.456
  123.456

  123.456
  123.4560
  123.45600
  123.456000
  123.4560000

  this is lowercase
  1.235E+02
  1.2346E+02
  1.23456E+02
  1.234560E+02
  1.2345600E+02

  123.
  123.5
  123.46
  123.456
  123.4560
  */
  • 좌우 정렬, 공백 대신 문자 채우기

    #include <iostream>
    #include <iomanip>
    
    int         main()
    {
        using namespace std;
    
        cout << -12345 << endl;
        cout << std::setw(10) << -12345 << endl;
        cout << std::setw(10) << std::left << -12345 << endl;
        cout << std::setw(10) << std::right << -12345 << endl;
        cout << std::setw(10) << std::internal << -12345 << endl;
        cout << endl;
        cout.fill('*');
        cout << std::setw(10) << -12345 << endl;
        cout << std::setw(10) << std::left << -12345 << endl;
        cout << std::setw(10) << std::right << -12345 << endl;
        cout << std::setw(10) << std::internal << -12345 << endl;
    }
    
    

/* stdout stderr
-12345
-12345
-12345
-12345

  • 12345

  • ****12345

  • 12345****

  • ***-12345

  • ****12345

  • /
    ```

'C++ > Library' 카테고리의 다른 글

C++ 정규 표현식 (Regular Expressions)  (0) 2021.03.29
C++ 흐름 상태 (Stream States)  (0) 2021.03.29
C++ ostream  (0) 2021.03.29
C++ istream  (0) 2021.03.29
C++ wstring  (0) 2021.03.26
C++/Library 2021. 3. 29. 23:55

ostream

cout

'C++ > Library' 카테고리의 다른 글

C++ 흐름 상태 (Stream States)  (0) 2021.03.29
C++ cout  (0) 2021.03.29
C++ istream  (0) 2021.03.29
C++ wstring  (0) 2021.03.26
C++ sstream  (0) 2021.03.26
C++/Library 2021. 3. 29. 23:55

istream

입력 범위 제한

setw() 함수

  • <iomanip> 라이브러리

    ```c++
    #include
    #include

    int main()
    {
    using namespace std;

    char buf[5];

    cin >> setw(5) >> buf;
    cout << buf << endl;
    cin >> setw(5) >> buf;
    cout << buf << endl;
    }

    /* stdin
    123456789

  • /

    /* stdout stderr
    1234
    5678

  • /


cin

getline

'C++ > Library' 카테고리의 다른 글

C++ cout  (0) 2021.03.29
C++ ostream  (0) 2021.03.29
C++ wstring  (0) 2021.03.26
C++ sstream  (0) 2021.03.26
C++ string  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:28

wstring

  • <string> 라이브러리

  • 일반적인 char의 범위를 넘어가는 유니코드 등의 글자를 저장할 때 사용되는 클래스이다.

    #include <iostream>
    #include <locale>
    #include <cstddef>
    
    int     main()
    {
        using namespace std;
    
        const wstring texts[] =
        {
            L"Hello", // English
            L"안녕하세요", // Korean
            L"Ñá", // Spanish
            L"forêt intérêt", // French
            L"Gesäß", // German
            L"取消波蘇日奇諾", // Chinese
            L"日本人のビット", // Japanese
            L"немного русский", // Russian
            L"ένα κομμάτι της ελληνικής", // Greek
            L"ਯੂਨਾਨੀ ਦੀ ਇੱਕ ਬਿੱਟ", // Punjabi (wtf?). xD
            L"کمی از ایران ", // Persian (I know it, from 300 movie)
            L"కానీ ఈ ఏమి నరకం ఉంది?", //Telugu (telu-what?)
            L"Но какво, по дяволите, е това?" //Bulgarian
        };
    
        std::locale::global(std::locale(""));
        std::wcout.imbue(std::locale());
    
        for (size_t i = 0; i < 13; ++i)
            wcout << texts[i] << endl;
    }
    
    /* stdout stderr
    Hello
    안녕하세요
    Na
    foret interet
    Gesaß
    取消波蘇日奇諾
    日本人のビット
    немного русский
    */
    • 처음엔 Hello 밖에 출력되지 않아서, 제어판 - 지역(Region)에 들어가서 Administrative 탭의 Language for non-Unicode programs를 한국어로 변경했다.

    • 이외의 외국어가 출력되지 않는 이유는 아마 언어팩이 설치되어있지 않아서 그런 것 같다.

'C++ > Library' 카테고리의 다른 글

C++ ostream  (0) 2021.03.29
C++ istream  (0) 2021.03.29
C++ sstream  (0) 2021.03.26
C++ string  (0) 2021.03.26
C++ STL 알고리즘 (Algorithms)  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:28

sstream

  • <sstream> 라이브러리

  • stringstream의 약자이다.

  • << : insertion operator

  • >> : extraction operator

상속 관계

  • istringstream, ostringstream, stringstream은 비슷하지만 약간 다른 부분이 존재한다.

    • istringstream<< 연산자는 정의되어있지 않다.

    • ostringstream>> 연산자는 정의되어있지 않다.

    <iosfwd>

    using istringstream = basic_istringstream<char, char_traits<char>, allocator<char>>;
    using ostringstream = basic_ostringstream<char, char_traits<char>, allocator<char>>;
    using stringstream  = basic_stringstream<char, char_traits<char>, allocator<char>>;

    <sstream>

    // CLASS TEMPLATE basic_istringstream
    template <class _Elem, class _Traits, class _Alloc>
    class basic_istringstream : public basic_istream<_Elem, _Traits> { // input stream associated with a character array
    };
    
    // CLASS TEMPLATE basic_ostringstream
    template <class _Elem, class _Traits, class _Alloc>
    class basic_ostringstream : public basic_ostream<_Elem, _Traits> { // output stream associated with a character array
    }
    
    // CLASS TEMPLATE basic_stringstream
    template <class _Elem, class _Traits, class _Alloc>
    class basic_stringstream
        : public basic_iostream<_Elem, _Traits> { // input/output stream associated with a character array
    }

기본 예제

  • stringstream 사용

    #include <iostream>
    #include <sstream>
    
    int         main()
    {
        using namespace std;
    
        stringstream ss;
        ss << "Hello, World";
        ss << '!';
    
        string str;
        ss >> str;
        cout << str << endl;
    
        ss.str("Hello World!");
        str = ss.str();
        cout << str << endl;
    
        ss.str("");
        cout << boolalpha << ss.str().empty() << endl;
    }
    
    /* stdout stderr
    Hello,
    Hello World!
    true
    */
  • 숫자 넣기

    #include <iostream>
    #include <sstream>
    
    int         main()
    {
        using namespace std;
    
        stringstream ss;
    
        ss << "12345 67.89";
    
        int     i;
        double  d;
    
        ss >> i >> d;
    
        cout << i << '|' << d << endl;
    }
    
    

/* stdout stderr
12345|67.89
*/


- `istringstream`, `ostringstream` 사용

  ```c++
  #include <iostream>
  #include <string>
  #include <sstream>

  template <typename T>
  std::string ToString(T x)
  {
    std::ostringstream osstream;
    osstream << x;
    return osstream.str();
  }

  template <typename T>
  bool        FromString(const std::string& str, T& x)
  {
    std::istringstream isstream(str);
    return (isstream >> x ? true : false);
  }

  int         main()
  {
    using namespace std;

    string my_str(ToString(3.141592));
    cout << my_str << endl;

    double d;
    if (FromString(my_str, d))
      cout << d << endl;
    else
      cout << "Cannot conver string to double\n";
    if (FromString("Hello", d))
      cout << d << endl;
    else
      cout << "Cannot conver string to double\n";
  }

  /* stdout stderr
  3.14159
  3.14159
  Cannot conver string to double
  */

'C++ > Library' 카테고리의 다른 글

C++ istream  (0) 2021.03.29
C++ wstring  (0) 2021.03.26
C++ string  (0) 2021.03.26
C++ STL 알고리즘 (Algorithms)  (0) 2021.03.26
C++ STL 반복자 (Iterators)  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:27

string

  • <string> 라이브러리

basic_string

  • string, wstring 등의 문자열 클래스는 다음과 같이 basic_string 클래스 템플릿이 인스턴스화된 것이다.

    <xstring>

    using string  = basic_string<char, char_traits<char>, allocator<char>>;
    using wstring = basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;
    #ifdef __cpp_lib_char8_t
    using u8string = basic_string<char8_t, char_traits<char8_t>, allocator<char8_t>>;
    #endif // __cpp_lib_char8_t
    using u16string = basic_string<char16_t, char_traits<char16_t>, allocator<char16_t>>;
    using u32string = basic_string<char32_t, char_traits<char32_t>, allocator<char32_t>>;

예제

  #include <iostream>
  #include <string>
  #include <vector>

  int     main()
  {
      using namespace std;

      const char* my_string = "my string";

      string  string1(my_string);
      string  string2(string1);
      string  string3(string1, 4);
      string  string4(string1, 4, 2);
      string  string5(my_string, 4);
      string  string6(10, 'A');

      vector<char> vec;
      for (auto& e : "Today is a good day")
          vec.push_back(e);

      string  string7(vec.begin(), vec.end());
      string  string8(vec.begin(), find(vec.begin(), vec.end(), 'a'));
      string  string9(std::to_string(1004));
      string9 += ' ' + std::to_string(3.14f);

      cout << "string1 : " << string1 << endl;
      cout << "string2 : " << string2 << endl;
      cout << "string3 : " << string3 << endl;
      cout << "string4 : " << string4 << endl;
      cout << "string5 : " << string5 << endl;
      cout << "string6 : " << string6 << endl;
      cout << "string7 : " << string7 << endl;
      cout << "string8 : " << string8 << endl;
      cout << "string9 : " << string9 << endl;
  }

  /* stdout stderr
  string1 : my string
  string2 : my string
  string3 : tring
  string4 : tr
  string5 : my s
  string6 : AAAAAAAAAA
  string7 : Today is a good day
  string8 : Tod
  string9 : 1004 3.140000
  */

getline

  • <iostream>include하면 <string>이 포함되는줄 알았는데, <string> 라이브러리를 include 하지 않으면 std::to_string(), std::getline()과 같은 함수를 쓸 수 없었다.

    • <iostream>에서 basic_string을 사용가능하도록 특정 라이브러리를 포함하지만, <string> 라이브러리가 포함되는 것은 아니다.
    #include <iostream>
    #include <string>
    
    int         main()
    {
        using namespace std;
    
        string buf;
    
        getline(cin, buf);
        cout << buf << endl;
    }
    
    /* stdin
    Hello World
    */
    
    /* stdout stderr
    Hello World
    */

대입, 교환, 덧붙이기, 삽입

  • 웬만한건 다 구현이 되어있다.

    #include <iostream>
    #include <string>
    
    int         main()
    {
      using namespace std;
    
      string str1("one");
      string str2;
    
      str2 = str1;
      cout << str2 << endl;
      str2 = "to";
      cout << str2 << endl;
      str2.insert(1, "w");
      cout << str2 << endl;
      str1 += ' ' + str2;
      str2.assign("three").append(" four").append(" five");
      cout << str2 << endl;
      str2.push_back('!');
    
      cout << "Before swap : " << str1 << ' ' << str2 << endl;
      std::swap(str1, str2);
      cout << "After swap : " << str1 << ' ' << str2 << endl;
    }
    
    /* stdout stderr
    one
    to
    two
    three four five
    Before swap : one two three four five!
    After swap : three four five! one two
    */

길이와 용량

  • vector와 비슷하게 길이(length)와 용량(capacity)을 따로 관리한다.

  • string::reserve() 함수는 최소한의 보장을 제공하므로 용량이 인자보다 더 클 수도 있다.

    #include <iostream>
    #include <string>
    
    int         main()
    {
      using namespace std;
    
      string my_str("012345678");
      string empty_str("");
    
      cout << "size : " << my_str.size() << endl;
      cout << "length : " << my_str.length() << endl;
      cout << "capacity : " << my_str.capacity() << endl;
      cout << "max_size : " << my_str.max_size() << endl;
    
      my_str.reserve(1000);
      cout << "capacity after reserve(1000) : " << my_str.capacity() << endl;
    
      cout << boolalpha;
      cout << "my_str is empty ? " << my_str.empty() << endl;
      cout << "empty_str is empty ? " << empty_str.empty() << endl;
    }
    
    /* stdout stderr
    size : 9
    length : 9
    capacity : 15
    max_size : 2147483647
    capacity after reserve(1000) : 1007
    my_str is empty ? false
    empty_str is empty ? true
    */

exception

  • std::exception으로 예외 처리를 받을 수 있다.

    • [] 연산자는 예외를 던지지 않는다.

      • 따라서 퍼포먼스가 중요한 경우 [] 연산자를 사용하는게 좋다.
    • string::at() 함수는 예외를 던진다.

      • 안정성이 중요한 경우 사용하는게 좋다.
    #include <iostream>
    #include <string>
    
    int         main()
    {
        using namespace std;
    
        string my_str("abcdefg");
    
        cout << my_str[0] << endl;
        cout << my_str[3] << endl;
    
        my_str[3] = 'Z';
        cout << my_str << endl;
    
        try
        {
            //my_str[100] = 'X';
            my_str.at(100) = 'X';
        }
        catch (std::exception& e)
        {
            cout << e.what() << endl;
        }
    }
    
    /* stdout stderr
    a
    d
    abcZefg
    invalid string position
    */

c-style string

  • char * 형태의 문자열로 변환하는 예제

    • string::c_str() 함수와 string::data() 함수를 통해 const char * 형태로 변환할 수 있다.

      • string::c_str() : null-terminated string이 아닌 경우, 해당 문자열을 복사하여 끝에 '\0'을 붙여준다.

      • string::data() : string 내부의 데이터를 그대로 리턴한다.

    #include <iostream>
    #include <string>
    
    int         main()
    {
      using namespace std;
    
      string my_str("abcdefg");
    
      cout << my_str.c_str() << endl;
      cout << int(my_str.c_str()[6]) << endl;
      cout << int(my_str.c_str()[7]) << endl;
    
      cout << my_str.data() << endl;
      cout << int(my_str.data()[6]) << endl;
      cout << int(my_str.data()[7]) << endl;
    }
    
    /* stdout stderr
    abcdefg
    103
    0
    */
  • string::copy() 함수로 char * 주소에 복사할 수도 있다.

    • 길이와 오프셋을 인자로 넣어야 한다.
    #include <iostream>
    #include <string>
    
    int         main()
    {
      using namespace std;
    
      string my_str("abcdefg");
    
      char buf[20] = { 0, };
    
      my_str.copy(buf, 5, 0);
      cout << buf << endl;
      my_str.copy(buf, 3, 1);
      cout << buf << endl;
    }
    
    /* stdout stderr
    abcde
    bcdde
    */

stringstream


wstring

'C++ > Library' 카테고리의 다른 글

C++ wstring  (0) 2021.03.26
C++ sstream  (0) 2021.03.26
C++ STL 알고리즘 (Algorithms)  (0) 2021.03.26
C++ STL 반복자 (Iterators)  (0) 2021.03.26
C++ multimap  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:23

STL 알고리즘 (Algorithms)

예제

  • 클래스를 원소로 넣을 경우 대부분 비교 연산자 오버로딩을 해놔야 한다.

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    int            main()
    {
      using namespace std;
    
      vector<int> container;
      for (int i = 0; i < 10; ++i)
        container.push_back(i);
    
      auto itr = min_element(container.begin(), container.end());
      cout << "Min element : " << *itr << endl;
    
      itr = max_element(container.begin(), container.end());
      cout << "Max element : " << *itr << "\n\n";
    
      itr = find(container.begin(), container.end(), 3);
      container.insert(itr, 128);
    
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    
      sort(container.begin(), container.end());
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    
      reverse(container.begin(), container.end());
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    Min element : 0
    Max element : 9
    
    0 1 2 128 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9 128
    128 9 8 7 6 5 4 3 2 1 0
    */

  • list의 경우 sort() 함수를 쓸 수 없고, 클래스 멤버 함수인 list::sort()를 사용해야 한다.

    #include <iostream>
    #include <list>
    #include <algorithm>
    
    int            main()
    {
      using namespace std;
    
      list<int> container;
      for (int i = 0; i < 10; ++i)
        container.push_back(i);
    
      auto itr = min_element(container.begin(), container.end());
      cout << "Min element : " << *itr << endl;
    
      itr = max_element(container.begin(), container.end());
      cout << "Max element : " << *itr << "\n\n";
    
      itr = find(container.begin(), container.end(), 3);
      container.insert(itr, 128);
    
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    
      container.sort();
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    
      container.reverse();
      for (auto& e : container) cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    Min element : 0
    Max element : 9
    
    0 1 2 128 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9 128
    128 9 8 7 6 5 4 3 2 1 0
    */

참고

'C++ > Library' 카테고리의 다른 글

C++ sstream  (0) 2021.03.26
C++ string  (0) 2021.03.26
C++ STL 반복자 (Iterators)  (0) 2021.03.26
C++ multimap  (0) 2021.03.26
C++ map  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:22

STL 반복자 (Iterators)

  • STL 컨테이너의 멤버들에 접근할 때 공통적인 방법으로 접근할 수 있도록 해주는 것이다.

  • iteratorconst_iterator는 사용할 때 크게 차이가 없는 듯하다.

  • 타이핑이 귀찮아서 보통 auto 키워드를 많이 사용하는 것 같다.

  • end() 함수는 맨 마지막 원소의 다음 주소를 가리킨다.

    • STL의 algorithm 함수들이 iterator로 firstlast를 받을 경우(처음과 끝), 마지막은 보통 end()가 오는 것으로 생각하여 포함시키지 않는다.

      [first, last)라고 생각하면 된다.

vector 예제

  • 원소를 전부 순회하려면 container.begin()부터 container.end() 전까지 반복자를 통해 돌면 된다.

    #include <iostream>
    #include <vector>
    
    int            main()
    {
      using namespace std;
    
      vector<int> container;
      for (int i = 0; i < 10; ++i)
        container.push_back(i);
    
      vector<int>::const_iterator itr;
      itr = container.begin();
      while (itr != container.end())
      {
        cout << *itr << ' ';
        ++itr;
      }
      cout << '\n';
    }
    
    /* stdout stderr
    0 1 2 3 4 5 6 7 8 9
    */
  • 간단하게 auto로 반복하는 예제

    #include <iostream>
    #include <vector>
    
    int            main()
    {
      using namespace std;
    
      vector<int> container;
      for (int i = 0; i < 10; ++i)
        container.push_back(i);
    
      for (auto itr = container.begin(); itr != container.end(); ++itr)
        cout << *itr << ' ';
      cout << '\n';
    
      for (auto& e : container)
        cout << e << ' ';
      cout << '\n';
    }
    
    /* stdout stderr
    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    */

list 예제

  • 문법은 vector와 비슷하다.

    #include <iostream>
    #include <list>
    
    int            main()
    {
      using namespace std;
    
      list<int> container;
      for (int i = 0; i < 10; ++i)
        container.push_back(i);
    
      for (auto itr = container.begin(); itr != container.end(); ++itr)
        cout << *itr << ' ';
      cout << '\n';
    
      for (auto& e : container)
        cout << e << ' ';
      cout << '\n';
    }
    
    /* stdout stderr
    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    */

set 예제

  #include <iostream>
  #include <set>

  int            main()
  {
    using namespace std;

    set<int> container;
    for (int i = 0; i < 10; ++i)
      container.insert(i);

    for (auto itr = container.begin(); itr != container.end(); ++itr)
      cout << *itr << ' ';
    cout << '\n';

    for (auto& e : container)
      cout << e << ' ';
    cout << '\n';
  }

  /* stdout stderr
  0 1 2 3 4 5 6 7 8 9
  0 1 2 3 4 5 6 7 8 9
  */

map 예제

  #include <iostream>
  #include <map>

  int            main()
  {
    using namespace std;

    map<int, char> container;
    for (int i = 0; i < 10; ++i)
      container.insert(make_pair(i, char(i + 65)));

    for (auto itr = container.begin(); itr != container.end(); ++itr)
      cout << itr->first << ' ' << itr->second << '\n';
    cout << '\n';

    for (auto& e : container)
      cout << e.first << ' ' << e.second << '\n';
    cout << '\n';
  }

  /* stdout stderr
  0 A
  1 B
  2 C
  3 D
  4 E
  5 F
  6 G
  7 H
  8 I
  9 J

  0 A
  1 B
  2 C
  3 D
  4 E
  5 F
  6 G
  7 H
  8 I
  9 J
  */

'C++ > Library' 카테고리의 다른 글

C++ string  (0) 2021.03.26
C++ STL 알고리즘 (Algorithms)  (0) 2021.03.26
C++ multimap  (0) 2021.03.26
C++ map  (0) 2021.03.26
C++ multiset  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:20

multimap

  • <map> 라이브러리

예제

  • key가 중복이 될 수 있는 map이다.

    #include <iostream>
    #include <map>
    
    int            main()
    {
      using namespace std;
    
      multimap<char, int> map;
    
      map.insert(std::pair<char, int>('a', 10));
      map.insert(std::pair<char, int>('c', 50));
      map.insert(std::pair<char, int>('b', 20));
      map.insert(std::pair<char, int>('a', 100));
    
      cout << map.count('a') << endl;
    
      for (auto& e : map)
        cout << e.first << ' ' << e.second << '\n';
    }
    
    /* stdout stderr
    2
    a 10
    a 100
    b 20
    c 50
    */

'C++ > Library' 카테고리의 다른 글

C++ STL 알고리즘 (Algorithms)  (0) 2021.03.26
C++ STL 반복자 (Iterators)  (0) 2021.03.26
C++ map  (0) 2021.03.26
C++ multiset  (0) 2021.03.26
C++ set  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:20

map

  • <map> 라이브러리

예제

  • key-value 쌍으로 이루어진 클래스이다.

    • first는 key를, second는 value를 가리킨다.

    • 자료를 저장할 때 오름차순으로 정렬한다.

    #include <iostream>
    #include <map>
    
    int            main()
    {
      using namespace std;
    
      map<char, int> map;
    
      map['c'] = 50;
      map['a'] = 10;
      map['b'] = 20;
    
      cout << map['a'] << endl;
    
      map['a'] = 100;
    
      cout << map['a'] << endl;
    
      for (auto& e : map)
        cout << e.first << ' ' << e.second << '\n';
    }
    
    /* stdout stderr
    10
    100
    a 100
    b 20
    c 50
    */

'C++ > Library' 카테고리의 다른 글

C++ STL 반복자 (Iterators)  (0) 2021.03.26
C++ multimap  (0) 2021.03.26
C++ multiset  (0) 2021.03.26
C++ set  (0) 2021.03.26
C++ Associative Containers  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:19

multiset

  • <set> 라이브러리

기본 예제

  • 중복을 허용하는 set이다.

    #include <iostream>
    #include <set>
    
    int            main()
    {
      using namespace std;
    
      multiset<string> str_set;
    
      str_set.insert("Hello");
      str_set.insert("World");
      str_set.insert("Hello");
    
      cout << "size : " << str_set.size() << endl;
    
      for (auto& e : str_set)
        cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    size : 3
    Hello Hello World
    */

'C++ > Library' 카테고리의 다른 글

C++ multimap  (0) 2021.03.26
C++ map  (0) 2021.03.26
C++ set  (0) 2021.03.26
C++ Associative Containers  (0) 2021.03.26
C++ Priority queue  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:19

set

  • <set> 라이브러리

예제

  • 원소가 중복되지 않는다.

    #include <iostream>
    #include <set>
    
    int            main()
    {
      using namespace std;
    
      set<string> str_set;
    
      str_set.insert("Hello");
      str_set.insert("World");
      str_set.insert("Hello");
    
      cout << "size : " << str_set.size() << endl;
    
      for (auto& e : str_set)
        cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    size : 2
    Hello World
    */

'C++ > Library' 카테고리의 다른 글

C++ map  (0) 2021.03.26
C++ multiset  (0) 2021.03.26
C++ Associative Containers  (0) 2021.03.26
C++ Priority queue  (0) 2021.03.26
C++ queue  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:18

Associative Containers

set

multiset

map

multimap

'C++ > Library' 카테고리의 다른 글

C++ multiset  (0) 2021.03.26
C++ set  (0) 2021.03.26
C++ Priority queue  (0) 2021.03.26
C++ queue  (0) 2021.03.26
C++ stack  (0) 2021.03.26
C++/Library 2021. 3. 26. 15:17

Priority queue

  • <queue> 라이브러리

기본 예제

  • 원소 간에 우선순위가 존재한다.

  • 템플릿으로 클래스를 사용하려면 비교 연산자 오버로딩을 해야한다.

    #include <iostream>
    #include <queue>
    
    int            main()
    {
      using namespace std;
    
      priority_queue<int> queue;
    
      for (const int n : {1, 8, 5, 6, 3, 4, 0, 9, 7, 2})
        queue.push(n);
    
      for (int i = 0; i < 10; ++i)
      {
        cout << queue.top() << endl;
        queue.pop();
      }
    }
    
    /* stdout stderr
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0
    */

'C++ > Library' 카테고리의 다른 글

C++ set  (0) 2021.03.26
C++ Associative Containers  (0) 2021.03.26
C++ queue  (0) 2021.03.26
C++ stack  (0) 2021.03.26
C++ Container Adaptors  (0) 2021.03.24
C++/Library 2021. 3. 26. 15:17

queue

  • <queue> 라이브러리

기본 예제

  • pop()으로 맨 앞의 원소를 제거한다.

    #include <iostream>
    #include <queue>
    
    int            main()
    {
      using namespace std;
    
      queue<int> queue;
    
      queue.push(1);
      queue.push(2);
      queue.push(3);
    
      cout << queue.front() << ' ' << queue.back() << endl;
      queue.pop();
      cout << queue.front() << ' ' << queue.back() << endl;
    }
    
    /* stdout stderr
    1 3
    2 3
    */

'C++ > Library' 카테고리의 다른 글

C++ Associative Containers  (0) 2021.03.26
C++ Priority queue  (0) 2021.03.26
C++ stack  (0) 2021.03.26
C++ Container Adaptors  (0) 2021.03.24
C++ deque (double-ended queue)  (0) 2021.03.24
C++/Library 2021. 3. 26. 15:16

stack

  • <stack> 라이브러리

기본 예제

  • pop()으로 맨 위의 원소를 제거한다.

    #include <iostream>
    #include <stack>
    
    int            main()
    {
      using namespace std;
    
      stack<int> stack;
    
      stack.push(1);
      stack.emplace(2);
      stack.emplace(3);
      cout << stack.top() << '\n';
      stack.pop();
      cout << stack.top() << '\n';
    }
    
    /* stdout stderr
    3
    2
    */

멤버 함수

  • push()

    • 값을 복사해서 넣는다.
  • emplace()

    • 원소를 새로 생성해서 넣기 때문에 복사 생성자나 이동 생성자가 호출되지 않는다.

'C++ > Library' 카테고리의 다른 글

C++ Priority queue  (0) 2021.03.26
C++ queue  (0) 2021.03.26
C++ Container Adaptors  (0) 2021.03.24
C++ deque (double-ended queue)  (0) 2021.03.24
C++ Sequences Containers  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:55

Container Adaptors

stack

queue

priority queue

'C++ > Library' 카테고리의 다른 글

C++ queue  (0) 2021.03.26
C++ stack  (0) 2021.03.26
C++ deque (double-ended queue)  (0) 2021.03.24
C++ Sequences Containers  (0) 2021.03.24
C++ STL 컨테이너 (STL Containers)  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:54

deque (double-ended queue)

  • <deque> 라이브러리

기본 예제

  • vector와 비슷하다.

  • push_front로 앞에서부터 추가할 수도 있다.

    #include <iostream>
    #include <deque>
    
    int            main()
    {
      using namespace std;
    
      deque<int> deq;
      for (int i = 0; i < 10; ++i)
      {
        deq.push_front(i);
        deq.push_back(i);
      }
      for (auto& e : deq)
        cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
    */

'C++ > Library' 카테고리의 다른 글

C++ stack  (0) 2021.03.26
C++ Container Adaptors  (0) 2021.03.24
C++ Sequences Containers  (0) 2021.03.24
C++ STL 컨테이너 (STL Containers)  (0) 2021.03.24
C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:53

Sequences Containers

vector

deque (double-ended queue)

list

slist

'C++ > Library' 카테고리의 다른 글

C++ Container Adaptors  (0) 2021.03.24
C++ deque (double-ended queue)  (0) 2021.03.24
C++ STL 컨테이너 (STL Containers)  (0) 2021.03.24
C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++ weak_ptr  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:51

STL 컨테이너 (STL Containers)

Simple Containers

  • pair

Sequences Containers

Container Adaptors

Associative Containers

Other types of Containers

  • bitset

  • valarray


참고

'C++ > Library' 카테고리의 다른 글

C++ deque (double-ended queue)  (0) 2021.03.24
C++ Sequences Containers  (0) 2021.03.24
C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++ weak_ptr  (0) 2021.03.24
C++ shared_ptr  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:50

표준 템플릿 라이브러리 (STL, Standard Template Libraries)

Standard Library와 STL의 차이

  • STL은 아래 4가지로 구성되어있고, 나머지는 그냥 Standard Library이다.

STL 컨테이너 (Containers)

STL 반복자 (Iterators)

STL 알고리즘 (Algorithms)

Functions

'C++ > Library' 카테고리의 다른 글

C++ Sequences Containers  (0) 2021.03.24
C++ STL 컨테이너 (STL Containers)  (0) 2021.03.24
C++ weak_ptr  (0) 2021.03.24
C++ shared_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24

'C++/Library'에 해당되는 글 51건