Namespaces
Variants

std::num_put<CharT,OutputIt>:: put, std::num_put<CharT,OutputIt>:: do_put

From cppreference.net
std::num_put
Member functions
num_put::put num_put::do_put
Défini dans l'en-tête <locale>
(1)
public :

iter_type put ( iter_type out, std:: ios_base & str,

char_type fill, bool val ) const ;
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, long val ) const ;
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, long long val ) const ;
(depuis C++11)
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, unsigned long val ) const ;
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, unsigned long long val ) const ;
(depuis C++11)
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, double val ) const ;
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, long double val ) const ;
iter_type put ( iter_type out, std:: ios_base & str,
char_type fill, const void * val ) const ;
(2)
protected :

virtual iter_type do_put ( iter_type out, std:: ios_base & str,

char_type fill, bool val ) const ;
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, long val ) const ;
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, long long val ) const ;
(depuis C++11)
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, unsigned long val ) const ;
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, unsigned long long val ) const ;
(depuis C++11)
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, double val ) const ;
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, long double val ) const ;
virtual iter_type do_put ( iter_type out, std:: ios_base & str,
char_type fill, const void * val ) const ;
1) Fonction membre publique, appelle la fonction membre virtuelle protégée do_put de la classe la plus dérivée.
2) Écrit des caractères dans la séquence de sortie out qui représentent la valeur de val , formatée selon les indicateurs de formatage str. flags ( ) et les facettes std::numpunct et std::ctype de la locale imbriquée dans le flux str . Cette fonction est appelée par tous les opérateurs de flux de sortie formatés, tels que std:: cout << n ; .

La conversion s'effectue en quatre étapes :

Table des matières

É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 uppercase = ( str. flags ( ) & std:: ios_base :: uppercase ) ;
fmtflags floatfield = ( str. flags ( ) & std:: ios_base :: floatfield ) ;
fmtflags showpos = ( str. flags ( ) & std:: ios_base :: showpos ) ;
fmtflags showbase = ( str. flags ( ) & std:: ios_base :: showbase ) ;
fmtflags showpoint = ( str. flags ( ) & std:: ios_base :: showpoint ) ;
  • Si le type de val est bool :
    • Si boolalpha == 0 , alors convertit val en type int et effectue une sortie entière.
    • Si boolalpha ! = 0 , obtient std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) si val == true ou std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) si val == false , et sort chaque caractère successif c de cette chaîne vers out avec * out ++ = c . Aucun traitement supplémentaire n'est effectué dans ce cas, la fonction retourne out .
  • Si le type de val est un type entier, le premier choix applicable parmi les suivants est sélectionné :
    • Si basefield == oct , utilisera le spécificateur de conversion % o .
    • Si basefield == hex && ! uppercase , utilisera le spécificateur de conversion % x .
    • Si basefield == hex , utilisera le spécificateur de conversion % X .
    • Si le type de val est signé, utilisera le spécificateur de conversion % d .
    • Si le type de val 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 : l pour long et unsigned long , ll pour long long et unsigned long long (depuis C++11) .
  • Si le type de val est un type à virgule flottante, le premier choix applicable parmi les suivants est sélectionné :
(jusqu'en C++11)
(depuis C++11)
(depuis C++11)
  • Si ! uppercase , utilisera le spécificateur de conversion % g .
  • Sinon, utilisera le spécificateur de conversion % G .
De plus :
  • Si le type de val est long double , le modificateur de longueur L est ajouté au spécificateur de conversion.
  • Si le type de val est un type à virgule flottante et floatfield ! = ( ios_base :: fixed | ios_base :: scientific ) (depuis C++11) , le modificateur de précision est ajouté et défini à str. precision ( ) . Sinon, aucune précision n'est spécifiée.
  • Pour les types entiers et à virgule flottante, si showpos est activé, le modificateur + est ajouté en préfixe.
  • Pour les types entiers, si showbase est activé, le modificateur # est ajouté en préfixe.
  • Pour les types à virgule flottante, si showpoint est activé, le modificateur # est ajouté en préfixe.
  • Si le type de val est void * , le spécificateur de conversion % p sera utilisé.
  • Une chaîne de caractères étroite est créée comme par un appel à std:: printf ( spec, val ) dans la locale "C", où spec est le spécificateur de conversion choisi.

Étape 2 : conversion spécifique aux paramètres régionaux

  • Chaque caractère c obtenu à l'Étape 1, autre que le point décimal '.' , est converti en CharT en appelant std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) . widen ( c ) .
  • Pour les types arithmétiques, le caractère séparateur de milliers, obtenu à partir de std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) , est inséré dans la séquence selon les règles de groupement fournies par std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) .
  • Les caractères de point décimal ( '.' ) sont remplacés par std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) .

Étape 3 : padding

  • Le drapeau d'ajustement est obtenu comme si par std :: fmtflags adjustfield = ( flags & ( std:: ios_base :: adjustfield ) ) et examiné pour identifier l'emplacement du remplissage, comme suit :
  • Si str. width ( ) est non nul (par ex. std::setw vient d'être utilisé) et que le nombre de CharT après l'Étape 2 est inférieur à str. width ( ) , alors des copies du caractère de fill sont insérées à la position indiquée par le remplissage pour amener la longueur de la séquence à str. width ( ) .

Dans tous les cas, str. width ( 0 ) est appelé pour annuler les effets de std::setw .

Étape 4 : sortie

Chaque caractère successif c de la séquence de CharT de l'Étape 3 est sorti comme si par * out ++ = c .

Paramètres

out - itérateur pointant vers le premier caractère à écraser
str - flux depuis lequel récupérer les informations de formatage
fill - caractère de remplissage utilisé lorsque les résultats doivent être complétés pour atteindre la largeur de champ
val - valeur à convertir en chaîne et à sortir

Valeur de retour

out

Notes

Le zéro initial généré par la spécification de conversion #o (résultant de la combinaison de std::showbase et std::oct par exemple) n'est pas compté comme un caractère de remplissage.

Lors du formatage d'une valeur à virgule flottante en hexadécimal (c'est-à-dire lorsque floatfield == ( std:: ios_base :: fixed | std:: ios_base :: scientific ) ), la précision du flux n'est pas utilisée ; à la place, le nombre est toujours imprimé avec suffisamment de précision pour représenter exactement la valeur.

(depuis C++11)

Exemple

Afficher un nombre en utilisant directement la facette, et démontrer une facette personnalisée :

#include <iostream>
#include <locale>
// this custom num_put outputs squares of all integers (except long long)
struct squaring_num_put : std::num_put<char>
{
    iter_type do_put(iter_type out, std::ios_base& str,
                     char_type fill, long val) const
    {
        return std::num_put<char>::do_put(out, str, fill, val * val);
    }
    iter_type do_put(iter_type out, std::ios_base& str,
                     char_type fill, unsigned long val) const
    {
        return std::num_put<char>::do_put(out, str, fill, val * val);
    }
};
int main()
{
    auto& facet = std::use_facet<std::num_put<char>>(std::locale());
    facet.put(std::cout, std::cout, '0', 2.71);
    std::cout << '\n';
    std::cout.imbue(std::locale(std::cout.getloc(), new squaring_num_put));
    std::cout << 6 << ' ' << -12 << '\n';
}

Sortie :

2.71
36 144

Une implémentation de operator<< pour un type défini par l'utilisateur.

#include <iostream>
#include <iterator>
#include <locale>
struct base { long x = 10; };
template<class CharT, class Traits>
std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os, const base& b)
{
    try
    {
        typename std::basic_ostream<CharT, Traits>::sentry s(os);
        if (s)
        {
            std::ostreambuf_iterator<CharT, Traits> it(os);
            std::use_facet<std::num_put<CharT>>(os.getloc())
                .put(it, os, os.fill(), b.x);
        }
    }
    catch (...)
    {
        // set badbit on os and rethrow if required
    }
    return os;
}
int main()
{
    base b;
    std::cout << b;
}

Sortie :

10

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 34 C++98 la surcharge bool utilisait des membres inexistants
truename et falsename de std::ctype
utilise ces membres
de std::numpunct
LWG 231 C++98 le modificateur de précision n'était ajouté que si
( flags & fixed ) ! = 0 ou str. precision ( ) > 0
supprimé ces conditions
LWG 282 C++98 les séparateurs de milliers n'étaient
insérés que pour les types entiers dans l'étape 2
également insérés pour
les types à virgule flottante
LWG 4084 C++11 "NAN" et "INF" ne pouvaient pas être affichés ils peuvent être affichés

Voir aussi

insère des données formatées
(fonction membre publique de std::basic_ostream<CharT,Traits> )