Namespaces
Variants

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

De fr.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) (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)
1-11) Fonction membre publique, appelle la fonction membre do_get de la classe la plus dérivée.
12-22) Lit les caractères de l'itérateur d'entré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 ) ;
**Note:** Le contenu HTML fourni ne contient aucun texte traduisible en dehors des balises ` `, `
` et ``. Tous les éléments visibles sont soit des termes C++ spécifiques (comme `fmtflags`, `basefield`, `boolalpha`, `std::ios_base`), soit du code C++ (entre les balises ``), qui ne doivent pas être traduits selon les instructions.
  • 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 in comme par char_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 par std::use_facet<std::ctype<CharT>>(str.getloc()).widen(), il est converti en le char correspondant.
    • 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é par std::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 char obtenu 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.

Étape 3 : conversion et stockage

  • La séquence de char s accumulée dans l'étape 2 est convertie en une valeur numérique :
L'entrée est analysée selon les règles de std::scanf .
(jusqu'en C++11)
L'entrée est analysée comme si par
(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 do_get(double) même si elles constituent une entrée valide pour strtod car l'étape 2 filtre les caractères 'P' et 'p' .

Les chaînes représentant l'infini ou NaN (par exemple "NaN" et "inf" ) sont rejetées par do_get(double) même si elles constituent une entrée valide pour strtod car l'étape 2 filtre les caractères tels que 'N' ou 'i' .

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