[C++] 표준 라이브러리를 사용하여 숫자 세 자리마다 쉼표 붙이기 Lu's…〃 Programing。

  기능을 숫자 형식(numeric format)이라고 하겠다

 출처는 MSDN | https://msdn.microsoft.com/ko-kr/goglobal/bb688127.aspx

 

 매우 많은 목적으로, 숫자를 표기할 자리마다 쉼표를 붙인다. MSDN에서는 숫자 형식이라고 하던데, 표준 명칭인지는 모르겠다. 일단 문서는 해당 단어를 사용한다.

 

우선 숫자 형식에 대해 알아보자.

한국에서는 당연하게 정수부에 1000 단위로 쉼표를 붙이고 소수점을 표시하기 위해 정수부가 끝나고 마침표를 찍는다. 하지만 독일에서는 반대다! 1000 단위로 마침표를 찍고, 소수점을 표시하기 위해 쉼표를 찍는다.

 

 대체로 프로그래밍을 배우는 초기 단계에서 해당 기능을 구현해봤겠지만 이런 보편적인 기능은 왠지 표준에 있을 같다. 그런 생각을 하고 찾아보니 정말 있더라.

 

 

  

 국가나 문화에 따라 달라지는 것이 있다. 통화 단위, 시간 표시, 그리고 숫자 형식. 외에도 달라지는 것이 있을 있기 때문에 C++ 표준위원회에서는 std::locale이라는 클래스로 포맷들을 캡슐화 두었다. 포맷(통화 단위, 시간 표시, 숫자 형식) facet이라고 부른다. facet locale "설치"하는 식으로 사용할 있다.

 

 어떻게 설치하느냐, 그것은 정말로 간단하다.

 

    // 기본 로케일 생성

    std::locale loc"ko" };

    // facet 설치하여 새로운 로케일을 만든다.

    std::locale new_loclocnew std::num_put<char>{} };

 

  new_loc std::num_put<char> 설치한 로케일이다. 줄로 쓰기 위해 loc new_loc 안에서 생성해도 된다.

 

new_loc 사용하기 위해서는 std::streambuf 연결할 필요가 있다. 어떻게 하느냐, imbue 함수를 사용한다.


 예를 들어, std::cout 설치한다고 하면 코드는 다음과 같다.

 

    std::locale loc"ko" };
    std::locale new_loclocnew std::num_put<char>{} };
    std::cout.imbue(new_loc);

 

물론, 숫자 형식을 cout 말고 다른 곳에 쓰려는 사람이 많을 것이다. 경우에는 std::ostringstream 이용하자.

 

template<typename T>
std::
string ConvertNumericFormat(std::localelocT numeric)
{
    static_assert(std::is_arithmetic<T>::value, "numeric format is only number.");
 
    using stream_t = std::ostringstream;
    using iter_t = stream_t::_Iter;
 
    stream_t stream;
    stream.imbue(loc);


    std::use_facet<std::num_put<char>>(loc).put(iter_t(stream), stream' 'numeric);
    return stream.str();
}

 



 마지막으로, 성능은 책임지지 않는다. 국제화를 고려하지 않는 경우라면 숫자 형식을 구현하기에는 번잡스럽고 표준 함수로만 구현하고 싶은 경우에나 만하지, 실시간으로 점수가 갱신되어야 하는 게임 같은 곳에 사용하기에는 성능이 허용 가능한지 체크해보는 것이 좋을 것이다.




덧글

댓글 입력 영역