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) | (depuis 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) | (depuis 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) | (depuis 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) | (depuis 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 de la classe la plus dérivée.in et génère la valeur du type de v, en tenant compte des indicateurs de formatage du flux d'E/S provenant de str.flags(), des règles de classification de caractères de std::use_facet<std::ctype<CharT>>(str.getloc()) et des caractères de ponctuation numérique de std::use_facet<std::numpunct<CharT>>(str.getloc()). Cette fonction est appelée par tous les opérateurs de flux d'entrée formatés tels que std::cin >> n;.La conversion se déroule en trois étapes :
Étape 1 : sélection du spécificateur de conversion
- Les indicateurs de format d'E/S sont obtenus, comme si par
- fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
- fmtflags boolalpha = ( str. flags ( ) & std:: ios_base :: boolalpha ) ;
`, `
` et `
- Si le type de v est un type entier, le premier choix applicable parmi les cinq suivants est sélectionné :
- Si basefield == oct , utilisera le spécificateur de conversion % o
- Si basefield == hex , utilisera le spécificateur de conversion % X
- Si basefield == 0 , utilisera le spécificateur de conversion % i
- Si le type de v est signé, utilisera le spécificateur de conversion % d
- Si le type de v est non signé, utilisera le spécificateur de conversion % u
- Pour les types entiers, le modificateur de longueur est ajouté à la spécification de conversion si nécessaire : h pour short et unsigned short , l pour long et unsigned long , ll pour long long et unsigned long long (depuis C++11)
- Si le type de v est float , la spécificateur de conversion % g sera utilisé
- Si le type de v est double , la spécificateur de conversion % lg sera utilisé
- Si le type de v est long double , la spécificateur de conversion % Lg sera utilisé
- Si le type de v est void * , la spécificateur de conversion % p sera utilisé
- Si le type de v est bool et boolalpha == 0 , procède comme si le type de v était long , sauf pour la valeur à stocker dans v à l'étape 3.
-
Si le type de
v
est
bool
et
boolalpha
!
=
0
, les étapes 2 et 3 sont remplacées par :
- Les caractères successifs obtenus de l'itérateur d'entrée in sont comparés aux séquences de caractères obtenues de std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) et std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) uniquement dans la mesure nécessaire pour identifier la correspondance unique. L'itérateur d'entrée in est comparé à end uniquement lorsque nécessaire pour obtenir un caractère.
- Si la séquence cible est identifiée de manière unique, v est défini sur la valeur bool correspondante. Sinon, false est stocké dans v et std::ios_base::failbit est assigné à err . Si aucune correspondance unique n'a pu être trouvée avant la fin de l'entrée ( in == end ), err | = std:: ios_base :: eofbit est exécuté.
Étape 2 : extraction des caractères
- Si
in == end, l'étape 2 se termine immédiatement, aucun autre caractère n'est extrait. - Le caractère suivant est extrait de
incomme parchar_type ct = *in;:- Si le caractère correspond à l'un de
"0123456789abcdefxABCDEFX+-"(jusqu'à C++11)"0123456789abcdefpxABCDEFPX+-"(depuis C++11), élargi au char_type de la locale comme parstd::use_facet<std::ctype<CharT>>(str.getloc()).widen(), il est converti en lecharcorrespondant. - Si le caractère correspond au séparateur de point décimal (
std::use_facet<std::numpunct<CharT>>(str.getloc()).decimal_point())), il est remplacé par'.'. - Si le caractère correspond au séparateur de milliers (
std::use_facet<std::numpunct<CharT>>(str.getloc()).thousands_sep()) et que la séparation des milliers est utilisée (comme déterminé parstd::use_facet<std::numpunct<CharT>>(str.getloc()).grouping().length() != 0), alors si le point décimal'.'n'a pas encore été accumulé, la position du caractère est mémorisée, mais le caractère est sinon ignoré. Si le point décimal a déjà été accumulé, le caractère est rejeté et l'étape 2 se termine. - Dans tous les cas, une vérification est faite pour savoir si le
charobtenu des étapes précédentes est autorisé dans le champ d'entrée qui serait analysé par std::scanf compte tenu du spécificateur de conversion sélectionné à l'étape 1. S'il est autorisé, il est accumulé dans un tampon temporaire et l'étape 2 se répète. S'il n'est pas autorisé, l'étape 2 se termine.
- Si le caractère correspond à l'un de
Étape 3 : conversion et stockage
- La séquence de char s accumulée dans l'étape 2 est convertie en une valeur numérique :
|
(jusqu'en C++11) |
|
(depuis C++11) |
- Si la fonction de conversion échoue à convertir l'intégralité du champ, la valeur 0 est stockée dans v .
- Si le type de v est un type entier signé et que la fonction de conversion produit une valeur positive ou négative trop grande pour y tenir, la valeur représentable la plus positive ou la plus négative est stockée dans v , respectivement.
- Si le type de v est un type entier non signé et que la fonction de conversion produit une valeur qui n'y tient pas, la valeur représentable la plus positive est stockée dans v .
- Dans tous les cas, si la fonction de conversion échoue std::ios_base::failbit est assigné à err .
-
Sinon, le résultat numérique de la conversion est stocké dans
v
.
- Si le type de v est bool et que boolalpha n'est pas défini, alors si la valeur à stocker est 0 , false est stocké, si la valeur à stocker est 1 , true est stocké, pour toute autre valeur std::ios_base::failbit est assigné à err et true est stocké.
- Ensuite, le regroupement de chiffres est vérifié. si la position de l'un des séparateurs de milliers ignorés lors de l'étape 2 ne correspond pas au regroupement fourni par std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) , std::ios_base::failbit est assigné à err .
- Si l'étape 2 a été terminée par le test in == end , err | = std:: ios_base :: eofbit est exécuté pour définir le bit eof.
Valeur de retour
in
Notes
Avant les résolutions de LWG issue 23 et LWG issue 696 , v restait inchangé si une erreur se produit.
Avant la résolution de
LWG issue 221
, les chaînes représentant des entiers hexadécimaux (par exemple
"0xA0"
) étaient rejetées par
do_get(int)
même si elles constituent une entrée valide pour
strtol
car l'étape 2 filtre les caractères
'X'
et
'x'
.
Avant la résolution de LWG issue 1169 , la conversion d'une chaîne de nombre négatif en entier non signé pouvait produire zéro (car la valeur représentée par la chaîne est inférieure à ce que le type cible peut représenter).
|
Avant la résolution de
LWG issue 2381
, les chaînes représentant des nombres hexadécimaux à virgule flottante avec exposants (par exemple
"0x1.23p-10"
) étaient rejetées par
Les chaînes représentant l'infini ou NaN (par exemple
"NaN"
et
"inf"
) sont rejetées par
|
(depuis C++11) |
Exemple
Une implémentation de
operator>>
pour un type défini par l'utilisateur.
#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; }
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 17 | C++98 | le processus d'analyse des valeurs booléennes textuelles était erroné | corrigé |
| LWG 18 | C++98 |
la surcharge de
get
prenant une valeur
bool
&
était manquante
|
ajoutée |
| LWG 23 | C++98 | un dépassement en entrée entraînait un comportement indéfini | dépassement géré |
| LWG 154 | C++98 | le spécificateur de conversion pour double était % g (identique à float ) | changé en % lg |
| LWG 221 | C++98 |
do_get
n'analysait pas
'x'
et
'X'
alors que
strtol
les analysait
|
rendu 'x' et 'X' analysés |
| LWG 275 | C++98 |
get
avait une surcharge prenant une valeur
short
&
au lieu de
float
&
|
corrigé |
| LWG 358 | C++98 | les séparateurs de milliers après la virgule décimale étaient ignorés | l'étape 2 est terminée si rencontrés |
| LWG 696 | C++98 | le résultat restait inchangé en cas d'échec de conversion | mis à zéro |
| LWG 1169 | C++98 | la gestion du dépassement était incohérente entre les types à virgule flottante |
rendue cohérente
avec
strtof
/
strtod
|
| LWG 2381 | C++11 |
do_get
n'analysait pas
'p'
et
'P'
alors que
strtod
les analysait
|
rendu 'p' et 'P' analysés |
Voir aussi
|
extrait des données formatées
(fonction membre publique de
std::basic_istream<CharT,Traits>
)
|