std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get
public:
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, bool& v ) const;
|
(1) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v ) const;
|
(2) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long long& v ) const;
|
(3) | (C++11부터) |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned short& v ) const;
|
(4) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned int& v ) const;
|
(5) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned long& v ) const;
|
(6) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned long long& v ) const;
|
(7) | (C++11부터) |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, float& v ) const;
|
(8) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, double& v ) const;
|
(9) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long double& v ) const;
|
(10) | |
iter_type get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, void*& v ) const;
|
(11) | |
protected:
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, bool& v ) const;
|
(12) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v ) const;
|
(13) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long long& v ) const;
|
(14) | (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;
|
(15) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned int& v ) const;
|
(16) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, unsigned long& v ) const;
|
(17) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err,
unsigned long long& v ) const;
|
(18) | (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;
|
(19) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, double& v ) const;
|
(20) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long double& v ) const;
|
(21) | |
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, void*& v ) const;
|
(22) | |
do_get를 호출합니다.in 의 타입 값을 생성하며 v, I/O 스트림 형식 플래그를 str.flags()에서, 문자 분류 규칙을 std::use_facet<std::ctype<CharT>>(str.getloc())에서, 숫자 구두점 문자를 std::use_facet<std::numpunct<CharT>>(str.getloc())에서. 이 함수는 std::cin >> n;와 같은 모든 형식화된 입력 스트림 연산자에 의해 호출됩니다.변환은 세 단계로 발생합니다:
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 가 실행됩니다.
2단계: 문자 추출
- 만약
in == end이면, 2단계가 즉시 종료되며 더 이상 문자를 추출하지 않습니다. - 다음 문자는
in에서 마치char_type ct = *in;에 의해 추출되는 것처럼 추출됩니다:- 문자가
"0123456789abcdefxABCDEFX+-"(C++11까지)"0123456789abcdefpxABCDEFPX+-"(C++11부터) 중 하나와 일치하고,std::use_facet<std::ctype<CharT>>(str.getloc()).widen()에 의해 로캘의 char_type으로 확장된 경우, 해당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)
|