Namespaces
Variants

std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get

cppreference.net에서
 
 
 
 
 
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)
1-11) 공용 멤버 함수이며, 가장 파생된 클래스의 멤버 함수 do_get를 호출합니다.
12-22) 입력 반복자에서 문자를 읽고 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 ) ;
**참고**: 제공된 HTML 코드는 이미 C++ 코드 조각으로, 번역이 필요한 일반 텍스트가 포함되어 있지 않습니다. 모든 내용이 ` ` 태그 내에 있어 C++ 코드로 간주되므로, 지시사항에 따라 번역하지 않고 원본을 그대로 유지했습니다.
  • 만약 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 시퀀스는 숫자 값으로 변환됩니다:
입력은 std::scanf 의 규칙에 따라 파싱됩니다.
(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' 문자를 걸러내기 때문에 do_get(double) 에 의해 거부되었습니다.

무한대 또는 NaN(Not-a-Number)을 나타내는 문자열들(예: "NaN" 및 "inf" )은 strtod 에 유효한 입력임에도 불구하고 2단계에서 'N' 또는 'i' 와 같은 문자를 걸러내기 때문에 do_get(double) 에 의해 거부됩니다.

(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)