(1) | ||
public: iter_type get( iter_type in, iter_type end, std::ios_base& str, std::ios_base::iostate& err, bool& v ) const; | ||
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; | (since 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; | (since 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, std::ios_base::iostate& err, bool& v ) const; | ||
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; | (since 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, unsigned long long& v ) const; | (since 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
of the most derived class.in
and generates the value of the type of v
, taking into account I/O stream formatting flags from str.flags()
, character classification rules from std::use_facet<std::ctype<CharT>>(str.getloc())
, and numeric punctuation characters from std::use_facet<std::numpunct<CharT>>(str.getloc())
. This function is called by all formatted input stream operators such as std::cin >> n;
.Conversion occurs in three stages:
fmtflags basefield = (str.flags() & std::ios_base::basefield);
fmtflags boolalpha = (str.flags() & std::ios_base::boolalpha);
v
is an integer type, the first applicable choice of the following five is selected: basefield == oct
, will use conversion specifier %o
basefield == hex
, will use conversion specifier %X
basefield == 0
, will use conversion specifier %i
v
is signed, will use conversion specifier %d
v
is unsigned, will use conversion specifier %u
h
for short and unsigned short, l
for long and unsigned long, ll
for long long
and unsigned long long
(since C++11) v
is float, will use conversion specifier %g
v
is double, will use conversion specifier %lg
v
is long double, will use conversion specifier %Lg
v
is void*, will use conversion specifier %p
v
is bool and boolalpha == 0
, proceeds as if the type of v
is long, except for the value to be stored in v
in stage 3. v
is bool and boolalpha != 0
, the following replaces stages 2 and 3: in
are matched against the character sequences obtained from std::use_facet<std::numpunct<CharT>>(str.getloc()).falsename()
and std::use_facet<std::numpunct<CharT>>(str.getloc()).truename()
only as necessary as to identify the unique match. The input iterator in
is compared to end
only when necessary to obtain a character. v
is set to the corresponding bool value. Otherwise false
is stored in v
and std::ios_base::failbit
is assigned to err
. If unique match could not be found before the input ended (in == end
), err |= std::ios_base::eofbit
is executed. in == end
, stage 2 is terminated immediately, no further characters are extracted. in
as if by char_type ct = *in;
: "0123456789abcdefxABCDEFX+-"
(until C++11)"0123456789abcdefpxABCDEFPX+-"
(since C++11), widened to the locale's char_type as if by std::use_facet<std::ctype<CharT>>(str.getloc()).widen()
, it is converted to the corresponding char
. std::use_facet<std::numpunct<CharT>>(str.getloc()).decimal_point())
), it is replaced by '.'
. std::use_facet<std::numpunct<CharT>>(str.getloc()).thousands_sep()
) and the thousands separation is in use (as determined by std::use_facet<std::numpunct<CharT>>(str.getloc()).grouping().length() != 0
), then if the decimal point '.'
has not yet been accumulated, the position of the character is remembered, but the character is otherwise ignored. If the decimal point has already been accumulated, the character is discarded and stage 2 terminates. std::scanf
given the conversion specifier selected in stage 1. If it is allowed, it is accumulated in a temporary buffer and stage 2 repeats. If it is not allowed, stage 2 terminates. The input is parsed according to the rules of std::scanf . | (until C++11) |
| (since C++11) |
0
is stored in v
. v
is a signed integer type and the conversion function results in a positive or negative value too large to fit in it, the most positive or negative representable value is stored in v
, respectively. v
is an unsigned integer type and the conversion function results in a value that does not fit in it, the most positive representable value is stored in v
. std::ios_base::failbit
is assigned to err
. v
. v
is bool and boolalpha is not set, then if the value to be stored is 0
, false
is stored, if the value to be stored is 1
, true
is stored, for any other value std::ios_base::failbit
is assigned to err
and true
is stored. std::use_facet<std::numpunct<CharT>>(str.getloc()).grouping()
, std::ios_base::failbit
is assigned to err
. in == end
, err |= std::ios_base::eofbit
is executed to set the eof bit. in
.
Before the resolutions of LWG issue 23 and LWG issue 696, v
was left unchanged if an error occurs.
Before the resolution of LWG issue 221, strings representing hexadecimal integers (e.g. "0xA0"
) were rejected by do_get(int)
even if they are valid input to strtol
because stage 2 filters out characters 'X'
and 'x'
.
Before the resolution of LWG issue 1169, converting a negative number string into an unsigned integer might produce zero (since the value represented by the string is smaller than what the target type can represent).
Before the resolution of LWG issue 2381, strings representing hexadecimal floating-point numbers with exponents (e.g. The strings representing infinity or not-a-number (e.g. | (since C++11) |
An implementation of operator>>
for a user-defined type.
#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; }
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 17 | C++98 | the process of parsing text boolean values was errornous | corrected |
LWG 18 | C++98 | the overload of get taking bool& value was missing | added |
LWG 23 | C++98 | overflowing input resulted in undefined behavior | overflow handled |
LWG 154 | C++98 | the conversion specifier for double was %g (same as float) | changed to %lg |
LWG 221 | C++98 | do_get did not parse 'x' and 'X' while strtol parsed them | made 'x' and 'X' parsed |
LWG 275 | C++98 | get had an overload taking short& value instead of float& | corrected |
LWG 358 | C++98 | thousand separators after the decimal point were ignored | stage 2 is terminated if encountered |
LWG 696 | C++98 | the result was unchanged on conversion failure | set to zero |
LWG 1169 | C++98 | overflow handling was inconsistent between floating-point types | made consistent with strtof /strtod |
LWG 2381 | C++11 | do_get did not parse 'p' and 'P' while strtod parsed them | made 'p' and 'P' parsed |
extracts formatted data (public member function of std::basic_istream<CharT,Traits> ) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/locale/num_get/get