Showing content from https://en.cppreference.com/w/cpp/language/../algorithm/../../cpp/../cpp/locale/num_get/get.html below:
std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get - cppreference.com
(1) (since C++11) (since C++11) (2) (since C++11) (since C++11)
1) Public member function, calls the member function do_get
of the most derived class.
2)
Reads characters from the input iterator
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:
[edit] Stage 1: conversion specifier selection
- I/O format flags are obtained, as if by
-
fmtflags basefield = (str.flags() & std::ios_base::basefield);
-
fmtflags boolalpha = (str.flags() & std::ios_base::boolalpha);
- If the type of v is an integer type, the first applicable choice of the following five is selected:
-
If basefield == oct, will use conversion specifier %o
-
If basefield == hex, will use conversion specifier %X
-
If basefield == 0, will use conversion specifier %i
-
If the type of v is signed, will use conversion specifier %d
-
If the type of v is unsigned, will use conversion specifier %u
- For integer types, length modifier is added to the conversion specification if necessary: h for short and unsigned short, l for long and unsigned long, ll for long long and unsigned long long(since C++11)
- If the type of v is float, will use conversion specifier %g
- If the type of v is double, will use conversion specifier %lg
- If the type of v is long double, will use conversion specifier %Lg
- If the type of v is void*, will use conversion specifier %p
- If the type of 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.
- If the type of v is bool and boolalpha != 0, the following replaces stages 2 and 3:
- Successive characters obtained from the input iterator 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.
- If the target sequence is uniquely matched, 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.
[edit]
- If in == end, stage 2 is terminated immediately, no further characters are extracted.
- The next character is extracted from in as if by char_type ct = *in;:
- If the character matches one of "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.
- If the character matches the decimal point separator (std::use_facet<std::numpunct<CharT>>(str.getloc()).decimal_point())), it is replaced by '.'.
- If the character matches the thousands separator (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.
- In any case, the check is made whether the char obtained from the previous steps is allowed in the input field that would be parsed by 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.
[edit] Stage 3: conversion and storage
- The sequence of chars accumulated in stage 2 is converted to a numeric value:
- If the conversion function fails to convert the entire field, the value â0â is stored in v.
- If the type of 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.
- If the type of 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.
- In any case, if the conversion function fails std::ios_base::failbit is assigned to err.
- Otherwise, the numeric result of the conversion is stored in v.
- If the type of 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.
- After this, digit grouping is checked. if the position of any of the thousands separators discarded in stage 2 does not match the grouping provided by std::use_facet<std::numpunct<CharT>>(str.getloc()).grouping(), std::ios_base::failbit is assigned to err.
- If stage 2 was terminated by the test in == end, err |= std::ios_base::eofbit is executed to set the eof bit.
[edit] Return value
in
[edit] Notes
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. "0x1.23p-10") were rejected by do_get(double)
even if they are valid input to strtod because stage 2 filters out characters 'P' and 'p'.
The strings representing infinity or not-a-number (e.g. "NaN" and "inf") are rejected by do_get(double)
even if they are valid input to strtod
because stage 2 filters out characters such as 'N' or 'i'.
(since C++11) [edit] Example
An implementation of operator>>
for a user-defined type.
[edit] Defect reports
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 [edit] See also extracts formatted data
(public member function of std::basic_istream<CharT,Traits>
) [edit]
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4