std::num_put<CharT,OutputIt>:: put, std::num_put<CharT,OutputIt>:: do_put
|
헤더에 정의됨
<locale>
|
||
| (1) | ||
|
public
:
iter_type put
(
iter_type out,
std::
ios_base
&
str,
|
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long long val ) const ; |
(C++11 이후) | |
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long long val ) const ; |
(C++11 이후) | |
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, double val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long double val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, const void * val ) const ; |
||
| (2) | ||
|
protected
:
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
|
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long long val ) const ; |
(C++11부터) | |
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long long val ) const ; |
(C++11부터) | |
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, double val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long double val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, const void * val ) const ; |
||
do_put
를 호출합니다.
변환은 네 단계로 이루어집니다:
목차 |
Stage 1: 변환 지정자 선택
- I/O 형식 플래그는 다음과 같이 획득됩니다.
- fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
- fmtflags uppercase = ( str. flags ( ) & std:: ios_base :: uppercase ) ;
- fmtflags floatfield = ( str. flags ( ) & std:: ios_base :: floatfield ) ;
- fmtflags showpos = ( str. flags ( ) & std:: ios_base :: showpos ) ;
- fmtflags showbase = ( str. flags ( ) & std:: ios_base :: showbase ) ;
- fmtflags showpoint = ( str. flags ( ) & std:: ios_base :: showpoint ) ;
-
val
의 타입이
bool
인 경우:
- boolalpha == 0 이면, val 을 int 타입으로 변환하고 정수 출력을 수행합니다.
- boolalpha ! = 0 이면, val == true 인 경우 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) 를, val == false 인 경우 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) 를 획득하고, 해당 문자열의 각 연속 문자 c 를 out 에 * out ++ = c 로 출력합니다. 이 경우 추가 처리는 수행되지 않으며, 함수는 out 을 반환합니다.
-
val
의 타입이 정수 타입인 경우, 다음 중 첫 번째로 적용 가능한 선택이 수행됩니다:
- basefield == oct 이면, 변환 지정자 % o 를 사용합니다.
- basefield == hex && ! uppercase 이면, 변환 지정자 % x 를 사용합니다.
- basefield == hex 이면, 변환 지정자 % X 를 사용합니다.
- val 의 타입이 부호 있는(signed) 타입이면, 변환 지정자 % d 를 사용합니다.
- val 의 타입이 부호 없는(unsigned) 타입이면, 변환 지정자 % u 를 사용합니다.
- 정수 타입의 경우, 필요한 경우 변환 지정에 길이 수식자가 추가됩니다: long 및 unsigned long 에는 l , long long 및 unsigned long long 에는 ll (C++11부터) 이 사용됩니다.
- val 의 타입이 부동소수점 타입인 경우, 다음 중 첫 번째로 적용 가능한 선택이 수행됩니다:
|
(C++11 이전) |
|
(C++11 이후) |
-
- 만약 floatfield == std:: ios_base :: scientific && ! uppercase 이면, 변환 지정자 % e 를 사용합니다.
- 만약 floatfield == std:: ios_base :: scientific 이면, 변환 지정자 % E 를 사용합니다.
|
(C++11부터) |
-
- 만약 ! uppercase 이면, 변환 지정자 % g 를 사용합니다.
- 그렇지 않으면, 변환 지정자 % G 를 사용합니다.
-
또한:
- 만약 val 의 타입이 long double 이면, 길이 수정자 L 이 변환 지정자에 추가됩니다.
- 만약 val 의 타입이 부동소수점 타입 이고 floatfield ! = ( ios_base :: fixed | ios_base :: scientific ) (C++11부터) 이면, 정밀도 수정자가 추가되어 str. precision ( ) 로 설정됩니다. 그렇지 않으면 정밀도가 지정되지 않습니다.
- 정수 및 부동 소수점 타입 모두에 대해, showpos 가 설정된 경우 + 수정자가 앞에 추가됩니다.
- 정수 타입의 경우, showbase 가 설정된 경우 # 수정자가 앞에 추가됩니다.
- 부동 소수점 타입의 경우, showpoint 가 설정된 경우 # 수정자가 앞에 추가됩니다.
- val 의 타입이 void * 인 경우, 변환 지정자 % p 를 사용합니다.
- 좁은 문자 문자열은 "C" 로케일에서 std:: printf ( spec, val ) 호출처럼 생성되며, 여기서 spec 은 선택된 변환 지정자입니다.
Stage 2: 로케일 특정 변환
-
Stage 1에서 얻은 모든 문자
c
중 소수점
'.'
을 제외하고는
std::
use_facet
<
std::
ctype
<
CharT
>>
(
str.
getloc
(
)
)
.
widen
(
c
)
을 호출하여
CharT로 변환됩니다. - 산술 타입의 경우, std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) 에서 얻은 천 단위 구분 기호가 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) 에서 제공하는 그룹화 규칙에 따라 시퀀스에 삽입됩니다.
- 소수점 문자( '.' )는 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) 로 대체됩니다.
Stage 3: 패딩
-
조정 플래그는 다음과 같이 얻어진 것처럼
std
::
fmtflags
adjustfield
=
(
flags
&
(
std::
ios_base
::
adjustfield
)
)
패딩 위치를 식별하기 위해 검사되며, 다음과 같이 결정됩니다:
- 만약 adjustfield == std:: ios_base :: left 이면, 뒤에 패딩합니다.
- 만약 adjustfield == std:: ios_base :: right 이면, 앞에 패딩합니다.
- 만약 adjustfield == std:: ios_base :: internal 이고 표현에 부호 문자가 있는 경우, 부호 뒤에 패딩합니다.
- 만약 adjustfield == std:: ios_base :: internal 이고 Stage 1 표현이 0x 또는 0X로 시작하는 경우, x 또는 X 뒤에 패딩합니다.
- 그렇지 않으면, 앞에 패딩합니다.
-
만약
str.
width
(
)
이 0이 아니고(예:
std::setw
가 방금 사용된 경우) Stage 2 이후의
CharT개수가 str. width ( ) 보다 작으면, 패딩 위치에 fill 문자 사본이 삽입되어 시퀀스 길이를 str. width ( ) 으로 맞춥니다.
어떤 경우에도, str. width ( 0 ) 가 호출되어 std::setw 의 효과를 취소합니다.
Stage 4: 출력
연속적인 각 문자
c
는 Stage 3의
CharT
시퀀스로부터
*
out
++
=
c
와 같이 출력됩니다.
매개변수
| out | - | 덮어쓸 첫 번째 문자를 가리키는 반복자 |
| str | - | 서식 정보를 가져올 스트림 |
| fill | - | 결과를 필드 너비에 맞게 채울 때 사용되는 패딩 문자 |
| val | - | 문자열로 변환하여 출력할 값 |
반환값
out
참고 사항
변환 지정자 #o (예를 들어 std::showbase 와 std::oct 의 조합으로 생성된)에 의해 생성된 선행 제로는 패딩 문자로 간주되지 않습니다.
|
부동 소수점 값을 16진수 형식(즉, floatfield == ( std:: ios_base :: fixed | std:: ios_base :: scientific ) )으로 포맷할 때, 스트림의 정밀도는 사용되지 않습니다; 대신 값이 항상 정확하게 표현될 수 있을 만큼 충분한 정밀도로 숫자가 출력됩니다. |
(C++11부터) |
예제
facet을 직접 사용하여 숫자를 출력하고, 사용자 정의 facet을 보여줍니다:
#include <iostream> #include <locale> // this custom num_put outputs squares of all integers (except long long) struct squaring_num_put : std::num_put<char> { iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long val) const { return std::num_put<char>::do_put(out, str, fill, val * val); } iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long val) const { return std::num_put<char>::do_put(out, str, fill, val * val); } }; int main() { auto& facet = std::use_facet<std::num_put<char>>(std::locale()); facet.put(std::cout, std::cout, '0', 2.71); std::cout << '\n'; std::cout.imbue(std::locale(std::cout.getloc(), new squaring_num_put)); std::cout << 6 << ' ' << -12 << '\n'; }
출력:
2.71 36 144
사용자 정의 타입을 위한 operator<< 구현.
#include <iostream> #include <iterator> #include <locale> struct base { long x = 10; }; template<class CharT, class Traits> std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const base& b) { try { typename std::basic_ostream<CharT, Traits>::sentry s(os); if (s) { std::ostreambuf_iterator<CharT, Traits> it(os); std::use_facet<std::num_put<CharT>>(os.getloc()) .put(it, os, os.fill(), b.x); } } catch (...) { // set badbit on os and rethrow if required } return os; } int main() { base b; std::cout << b; }
출력:
10
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 수정된 동작 |
|---|---|---|---|
| LWG 34 | C++98 |
bool
오버로드가 존재하지 않는 멤버
truename 과 falsename 을 사용함 ( std::ctype 의 멤버) |
해당 멤버들을
std::numpunct 에서 사용 |
| LWG 231 | C++98 |
정밀도 수정자가 추가되는 조건:
( flags & fixed ) ! = 0 또는 str. precision ( ) > 0 |
해당 조건들 제거 |
| LWG 282 | C++98 |
1000단위 구분 기호가 2단계에서
정수형에만 삽입됨 |
부동소수점 타입에도
삽입됨 |
| LWG 4084 | C++11 | "NAN" 과 "INF" 출력 불가 | 출력 가능 |
참고 항목
|
형식화된 데이터 삽입
(
std::basic_ostream<CharT,Traits>
의 public member function)
|