std::num_get<CharT,InputIt>:: get, std::num_get<CharT,InputIt>:: do_get
| (1) | ||
|
public
:
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
|
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long long & v ) const ; |
(C++11 이후) | |
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned short & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned int & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned long & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned long long & v ) const ; |
(C++11 이후) | |
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, float & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, double & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long double & v ) const ; |
||
|
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, void * & v ) const ; |
||
| (2) | ||
|
protected
:
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
|
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long long & v ) const ; |
(C++11부터) | |
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned short & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned int & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, unsigned long & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std::
ios_base
::
iostate
&
err,
|
(C++11부터) | |
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, float & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, double & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, long double & v ) const ; |
||
|
virtual
iter_type do_get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
std:: ios_base :: iostate & err, void * & v ) const ; |
||
do_get
멤버 함수를 호출합니다.
변환은 세 단계로 이루어집니다:
목차 |
Stage 1: 변환 지정자 선택
- I/O 형식 플래그는 다음과 같이 획득됩니다.
- fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
- fmtflags boolalpha = ( str. flags ( ) & std:: ios_base :: boolalpha ) ;
- 만약 v 의 타입이 정수형(integer type)인 경우, 다음 다섯 가지 중 첫 번째로 적용 가능한 선택지가 선택됩니다:
- 만약 basefield == oct 이면, 변환 지정자 % o 를 사용합니다
- 만약 basefield == hex 이면, 변환 지정자 % X 를 사용합니다
- 만약 basefield == 0 이면, 변환 지정자 % i 를 사용합니다
- 만약 v 의 타입이 signed이면, 변환 지정자 % d 를 사용합니다
- 만약 v 의 타입이 unsigned이면, 변환 지정자 % u 를 사용합니다
- 정수 타입의 경우, 필요한 경우 변환 지정자에 길이 수정자가 추가됩니다: h 은 short 와 unsigned short 를 위해, l 은 long 와 unsigned long 를 위해 사용됩니다. , ll 은 long long 와 unsigned long long 를 위해 사용됩니다. (C++11부터)
- 만약 v 의 타입이 float 인 경우, 변환 지정자 % g 를 사용합니다.
- 만약 v 의 타입이 double 인 경우, 변환 지정자 % lg 를 사용합니다.
- 만약 v 의 타입이 long double 인 경우, 변환 지정자 % Lg 를 사용합니다.
- 만약 v 의 타입이 void * 인 경우, 변환 지정자 % p 를 사용합니다.
- 만약 v 의 타입이 bool 이고 boolalpha == 0 인 경우, v 의 타입이 long 인 것처럼 진행하되, 3단계에서 v 에 저장될 값은 예외로 합니다.
-
만약
v
의 타입이
bool
이고
boolalpha
!
=
0
인 경우, 다음 내용이 2단계와 3단계를 대체합니다:
- 입력 반복자 in 에서 얻은 연속적인 문자들은 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) 와 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) 에서 얻은 문자 시퀀스들과 필요에 따라 고유한 매치를 식별할 수 있을 때까지 비교됩니다. 입력 반복자 in 은 문자를 얻기 위해 필요할 때만 end 와 비교됩니다.
- 대상 시퀀스가 고유하게 매치되면, v 는 해당하는 bool 값으로 설정됩니다. 그렇지 않으면 false 가 v 에 저장되고 std::ios_base::failbit 이 err 에 할당됩니다. 입력이 끝나기 전에 고유한 매치를 찾을 수 없는 경우 ( in == end ), err | = std:: ios_base :: eofbit 가 실행됩니다.
Stage 2: 문자 추출
- 만약 in == end 이면, 2단계는 즉시 종료되며 더 이상의 문자를 추출하지 않습니다.
-
다음 문자는
char_type ct
=
*
in
;
와 같이
in
으로부터 추출됩니다:
- 문자가 다음 중 하나와 일치하면 "0123456789abcdefxABCDEFX+-" (C++11 이전) "0123456789abcdefpxABCDEFPX+-" (C++11 이후) , 로캘의 char_type으로 std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) . widen ( ) 와 같이 확장되어, 해당하는 char 로 변환됩니다.
- 문자가 소수점 구분자( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) ) )와 일치하면, '.' 로 대체됩니다.
- 문자가 천 단위 구분자( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) )와 일치하고 천 단위 구분이 사용 중인 경우( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) . length ( ) ! = 0 에 의해 결정됨), 만약 소수점 '.' 이 아직 누적되지 않았다면, 문자의 위치는 기억되지만 문자는 그 외에는 무시됩니다. 만약 소수점이 이미 누적되었다면, 문자는 버려지고 2단계는 종료됩니다.
- 모든 경우에, 이전 단계들에서 얻은 char 이 1단계에서 선택된 변환 지정자에 따라 std::scanf 에 의해 파싱될 입력 필드에서 허용되는지 확인합니다. 허용된다면, 임시 버퍼에 누적되고 2단계가 반복됩니다. 허용되지 않는다면, 2단계는 종료됩니다.
Stage 3: 변환 및 저장
- 단계 2에서 누적된 char 시퀀스는 숫자 값으로 변환됩니다:
|
(C++11 이전) |
|
(C++11 이후) |
- 변환 함수가 전체 필드를 변환하는 데 실패하면, 값 0 이 v 에 저장됩니다.
- v 의 타입이 부호 있는 정수 타입이고 변환 함수의 결과가 저장하기에 너무 큰 양수나 음수 값인 경우, 각각 표현 가능한 가장 큰 양수 값 또는 가장 작은 음수 값이 v 에 저장됩니다.
- v 의 타입이 부호 없는 정수 타입이고 변환 함수의 결과가 저장하기에 맞지 않는 값인 경우, 표현 가능한 가장 큰 양수 값이 v 에 저장됩니다.
- 어떤 경우든, 변환 함수가 실패하면 std::ios_base::failbit 이 err 에 할당됩니다.
-
그렇지 않으면, 변환의 숫자 결과가
v
에 저장됩니다.
- v 의 타입이 bool 이고 boolalpha가 설정되지 않은 경우, 저장될 값이 0 이면 false 가 저장되고, 저장될 값이 1 이면 true 가 저장되며, 다른 값인 경우 std::ios_base::failbit 가 err 에 할당되고 true 가 저장됩니다.
- 이후 숫자 그룹화가 검사됩니다. 2단계에서 버려진 천 단위 구분자의 위치가 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) 에서 제공하는 그룹화와 일치하지 않으면, std::ios_base::failbit 이 err 에 할당됩니다.
- 2단계가 in == end 테스트로 종료된 경우, err | = std:: ios_base :: eofbit 이 실행되어 eof 비트를 설정합니다.
반환값
in
참고 사항
LWG issue 23 과 LWG issue 696 의 해결 이전에는, 오류가 발생할 경우 v 가 변경되지 않은 상태로 유지되었습니다.
LWG issue 221
이 해결되기 전에는, 16진수 정수를 나타내는 문자열들(예:
"0xA0"
)이
strtol
에 유효한 입력값임에도 불구하고, 2단계에서
'X'
와
'x'
문자들을 걸러내기 때문에
do_get(int)
에 의해 거부되었습니다.
LWG issue 1169 가 해결되기 전에는, 음수 문자열을 부호 없는 정수로 변환할 때 0이 생성될 수 있었습니다(문자열이 나타내는 값이 대상 타입이 표현할 수 있는 값보다 작기 때문).
|
LWG 이슈 2381
이 해결되기 전에는, 지수를 포함하는 16진수 부동 소수점 숫자를 나타내는 문자열들(예:
"0x1.23p-10"
)이
strtod
에 유효한 입력임에도 불구하고 2단계에서
'P'
및
'p'
문자를 걸러내기 때문에
무한대 또는 NaN(Not-a-Number)을 나타내는 문자열들(예:
"NaN"
및
"inf"
)은
|
(C++11부터) |
예제
사용자 정의 타입을 위한
operator>>
구현 예제입니다.
#include <iostream> #include <iterator> #include <locale> struct base { long x; }; template<class CharT, class Traits> std::basic_istream<CharT, Traits>& operator >>(std::basic_istream<CharT, Traits>& is, base& b) { std::ios_base::iostate err = std::ios_base::goodbit; try // setting err could throw { typename std::basic_istream<CharT, Traits>::sentry s(is); if (s) // if stream is ready for input std::use_facet<std::num_get<CharT>>(is.getloc()).get(is, {}, is, err, b.x); } catch (std::ios_base::failure& error) { // handle the exception } return is; } int main() { base b; std::cin >> b; }
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 17 | C++98 | 텍스트 부울 값 파싱 과정에 오류가 있었음 | 수정됨 |
| LWG 18 | C++98 |
get
의
bool
&
값을 취하는 오버로드가 누락됨
|
추가됨 |
| LWG 23 | C++98 | 오버플로우 입력이 정의되지 않은 동작을 초래함 | 오버플로우 처리됨 |
| LWG 154 | C++98 | double 의 변환 지정자가 % g 였음 ( float 와 동일) | % lg 로 변경됨 |
| LWG 221 | C++98 |
do_get
이
'x'
와
'X'
를 파싱하지 않았지만
strtol
는 이를 파싱함
|
'x' 와 'X' 가 파싱되도록 수정됨 |
| LWG 275 | C++98 |
get
이
float
&
대신
short
&
값을 취하는 오버로드를 가짐
|
수정됨 |
| LWG 358 | C++98 | 소수점 이후의 천 단위 구분 기호가 무시됨 | 발견 시 2단계가 종료됨 |
| LWG 696 | C++98 | 변환 실패 시 결과가 변경되지 않음 | 0으로 설정됨 |
| LWG 1169 | C++98 | 부동 소수점 타입 간 오버플로우 처리 방식이 일관되지 않음 |
strtof
/
strtod
와 일관되게 수정됨
|
| LWG 2381 | C++11 |
do_get
이
'p'
와
'P'
를 파싱하지 않았지만
strtod
는 이를 파싱함
|
'p' 와 'P' 가 파싱되도록 수정됨 |
참고 항목
|
형식화된 데이터를 추출합니다
(
std::basic_istream<CharT,Traits>
의 public member function)
|