Namensräume
Varianten
Aktionen

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

Von cppreference.com
< cpp‎ | locale‎ | num put
 
 
 
 
std::num_put
Memberfunktionen
num_put::putnum_put::do_put
 
Definiert in Header <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;
(seit 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;
(seit 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;
(seit 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;
(seit 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) Öffentliche Memberfunktion, ruft die protected virtuelle Memberfunktion do_put der am weitesten abgeleiteten Klasse auf.
2) Schreibt Zeichen in die Ausgabesequenz out, die den Wert von val darstellen und gemäß den Formatierungsflags str.flags() und den Facetten std::numpunct sowie std::ctype der im Stream str eingebetteten Locale formatiert sind. Diese Funktion wird von allen formatierten Ausgabestream-Operatoren aufgerufen, wie z. B. std::cout << n;.

Die Konvertierung erfolgt in vier Schritten

Inhalt

[bearbeiten] Schritt 1: Auswahl des Konvertierungsspezifizierers

  • Die I/O-Formatflags werden abgerufen, als ob durch
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);
  • Wenn der Typ von val bool ist
    • Wenn boolalpha == 0, dann wird val in den Typ int konvertiert und die Integer-Ausgabe durchgeführt.
    • Wenn boolalpha != 0, wird std::use_facet<std::numpunct<CharT>>(str.getloc()).truename() erhalten, wenn val == true oder std::use_facet<std::numpunct<CharT>>(str.getloc()).falsename() erhalten wird, wenn val == false, und jedes aufeinanderfolgende Zeichen c dieser Zeichenkette wird mit *out++ = c nach out ausgegeben. In diesem Fall erfolgt keine weitere Verarbeitung, und die Funktion gibt out zurück.
  • Wenn der Typ von val ein Ganzzahltyp ist, wird die erste zutreffende Wahl aus den folgenden ausgewählt
    • Wenn basefield == oct, wird der Konvertierungsspezifizierer %o verwendet.
    • Wenn basefield == hex && !uppercase, wird der Konvertierungsspezifizierer %x verwendet.
    • Wenn basefield == hex, wird der Konvertierungsspezifizierer %X verwendet.
    • Wenn der Typ von val vorzeichenbehaftet ist, wird der Konvertierungsspezifizierer %d verwendet.
    • Wenn der Typ von val vorzeichenlos ist, wird der Konvertierungsspezifizierer %u verwendet.
  • Für Ganzzahltypen wird bei Bedarf ein Längenmodifikator zur Konvertierungsspezifikation hinzugefügt: l für long und unsigned long, ll für long long und unsigned long long(seit C++11).
  • Wenn der Typ von val ein Fließkommatyp ist, wird die erste zutreffende Wahl aus den folgenden ausgewählt
(bis C++11)
(seit C++11)
(seit C++11)
  • Wenn !uppercase, wird der Konvertierungsspezifizierer %g verwendet.
  • Andernfalls wird der Konvertierungsspezifizierer %G verwendet.
Außerdem
  • Wenn der Typ von val long double ist, wird der Längenmodifikator L zum Konvertierungsspezifizierer hinzugefügt.
  • Wenn der Typ von val ein Fließkommatyp ist und floatfield != (ios_base::fixed | ios_base::scientific)(seit C++11), wird der Präzisionsmodifikator hinzugefügt und auf str.precision() gesetzt. Andernfalls wird keine Präzision angegeben.
  • Für sowohl Ganzzahl- als auch Fließkommatypen wird, wenn showpos gesetzt ist, der Modifikator + vorangestellt.
  • Für Ganzzahltypen wird, wenn showbase gesetzt ist, der Modifikator # vorangestellt.
  • Für Fließkommatypen wird, wenn showpoint gesetzt ist, der Modifikator # vorangestellt.
  • Wenn der Typ von val void* ist, wird der Konvertierungsspezifizierer %p verwendet.
  • Eine schmale Zeichenkette wird erstellt, als ob durch einen Aufruf von std::printf(spec, val) in der "C"-Locale, wobei spec der gewählte Konvertierungsspezifizierer ist.

[bearbeiten] Schritt 2: Locale-spezifische Konvertierung

  • Jedes Zeichen c, das in Schritt 1 erhalten wurde, mit Ausnahme des Dezimalpunkts '.', wird zu CharT konvertiert, indem std::use_facet<std::ctype<CharT>>(str.getloc()).widen(c) aufgerufen wird.
  • Für arithmetische Typen wird das Tausendertrennzeichen, erhalten von std::use_facet<std::numpunct<CharT>>(str.getloc()).thousands_sep(), gemäß den Gruppierungsregeln, die von std::use_facet<std::numpunct<CharT>>(str.getloc()).grouping() bereitgestellt werden, in die Sequenz eingefügt.
  • Dezimalpunktzeichen ('.') werden durch std::use_facet<std::numpunct<CharT>>(str.getloc()).decimal_point() ersetzt.

[bearbeiten] Schritt 3: Auffüllen

  • Das Ausrichtungsflag wird abgerufen, als ob durch std::fmtflags adjustfield = (flags & (std::ios_base::adjustfield)) und wie folgt untersucht, um die Auffüllposition zu ermitteln
    • Wenn adjustfield == std::ios_base::left, wird danach aufgefüllt.
    • Wenn adjustfield == std::ios_base::right, wird davor aufgefüllt.
    • Wenn adjustfield == std::ios_base::internal und ein Vorzeichenzeichen in der Darstellung vorkommt, wird nach dem Vorzeichen aufgefüllt.
    • Wenn adjustfield == std::ios_base::internal und die Darstellung in Schritt 1 mit 0x oder 0X begann, wird nach dem x oder X aufgefüllt.
    • Andernfalls wird davor aufgefüllt.
  • Wenn str.width() ungleich Null ist (z. B. wenn std::setw gerade verwendet wurde) und die Anzahl der CharT's nach Schritt 2 kleiner als str.width() ist, dann werden Kopien des fill-Zeichens an der durch das Auffüllen angegebenen Position eingefügt, um die Länge der Sequenz auf str.width() zu bringen.

In jedem Fall wird str.width(0) aufgerufen, um die Auswirkungen von std::setw abzuschalten.

[bearbeiten] Schritt 4: Ausgabe

Jedes aufeinanderfolgende Zeichen c aus der Sequenz von CharT's aus Schritt 3 wird ausgegeben, als ob durch *out++ = c.

[bearbeiten] Parameter

out - Iterator, der auf das erste zu überschreibende Zeichen zeigt
str - Stream, aus dem die Formatierungsinformationen abgerufen werden
fill - Füllzeichen, das verwendet wird, wenn das Ergebnis auf die Feldbreite aufgefüllt werden muss
val - Zu konvertierender und auszugebender Wert

[bearbeiten] Rückgabewert

out

[bearbeiten] Hinweise

Die führende Null, die durch die Konvertierungsspezifikation #o erzeugt wird (z. B. als Ergebnis der Kombination von std::showbase und std::oct), wird nicht als Auffüllzeichen gezählt.

Beim Formatieren eines Fließkommawerts als Hexadezimalzahl (d. h. wenn floatfield == (std::ios_base::fixed | std::ios_base::scientific)) wird die Präzision des Streams nicht verwendet; stattdessen wird die Zahl immer mit ausreichender Präzision ausgegeben, um den Wert exakt darzustellen.

(seit C++11)

[bearbeiten] Beispiel

Eine Zahl mithilfe der Facette direkt ausgeben und eine benutzerdefinierte Facette demonstrieren

#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';
}

Ausgabe

2.71
36 144

Eine Implementierung von operator<< für einen benutzerdefinierten Typ.

#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;
}

Ausgabe

10

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 34 C++98 die bool-Überladung verwendete nicht existierende Member
truename und falsename von std::ctype
nutzen diese Member
von std::numpunct
LWG 231 C++98 der Präzisionsmodifikator wurde nur hinzugefügt, wenn
(flags & fixed) != 0 oder str.precision() > 0
diese Bedingungen wurden entfernt
LWG 282 C++98 die Tausendertrennzeichen wurden nur
für Integral-Typen in Schritt 2 eingefügt
auch eingefügt für
Gleitkommatypen
LWG 4084 C++11 "NAN" und "INF" konnten nicht ausgegeben werden sie können ausgegeben werden

[bearbeiten] Siehe auch

fügt formatierte Daten ein
(public member function of std::basic_ostream<CharT,Traits>) [bearbeiten]