Namespaces
Variants

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

From cppreference.net
std::num_get
Member functions
num_get::get num_get::do_get
(Anmerkung: Der bereitgestellte HTML-Code enthält keinen übersetzbaren Text, da alle Tags leer sind. Die HTML-Struktur wurde gemäß den Anforderungen unverändert beibehalten.)
(1)
public :

iter_type get ( iter_type in, iter_type end, std:: ios_base & str,

std:: ios_base :: iostate & err, bool & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long long & v ) const ;
(seit C++11)
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned short & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned int & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long long & v ) const ;
(seit C++11)
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, float & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, double & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long double & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, void * & v ) const ;
(2)
protected :

virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,

std:: ios_base :: iostate & err, bool & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long long & v ) const ;
(seit 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 ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned int & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long & v ) const ;
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 ;
(seit 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 ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, double & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long double & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, void * & v ) const ;
1) Öffentliche Memberfunktion, ruft die Memberfunktion do_get der abgeleitetesten Klasse auf.
2) Liest Zeichen vom Eingabe-Iterator in und erzeugt den Wert des Typs von v , unter Berücksichtigung der E/A-Stream-Formatierungsflags von str. flags ( ) , Zeichenklassifizierungsregeln von std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) und numerischen Interpunktionszeichen von std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . Diese Funktion wird von allen formatierten Eingabe-Stream-Operatoren wie std:: cin >> n ; aufgerufen.

Die Konvertierung erfolgt in drei Stufen:

Inhaltsverzeichnis

Stufe 1: Auswahl des Konvertierungsspezifizierers

  • I/O-Format-Flags werden abgerufen, als ob durch
fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
fmtflags boolalpha = ( str. flags ( ) & std:: ios_base :: boolalpha ) ;
  • Wenn der Typ von v ein Ganzzahltyp ist, wird die erste zutreffende Wahl der folgenden fünf ausgewählt:
Wenn basefield == oct , wird Konvertierungsspezifizierer % o verwendet
Wenn basefield == hex , wird Konvertierungsspezifizierer % X verwendet
Wenn basefield == 0 , wird Konvertierungsspezifizierer % i verwendet
Wenn der Typ von v signiert ist, wird Konvertierungsspezifizierer % d verwendet
Wenn der Typ von v unsigniert ist, wird Konvertierungsspezifizierer % u verwendet
  • Für Ganzzahltypen wird bei Bedarf ein Längenmodifikator zur Konversionsspezifikation hinzugefügt: h für short und unsigned short , l für long und unsigned long , ll für long long und unsigned long long (seit C++11)
  • Wenn der Typ von v float ist, wird die Konversionsspezifikation % g verwendet.
  • Wenn der Typ von v double ist, wird die Konversionsspezifikation % lg verwendet.
  • Wenn der Typ von v long double ist, wird die Konversionsspezifikation % Lg verwendet.
  • Wenn der Typ von v void * ist, wird die Konversionsspezifikation % p verwendet.
  • Wenn der Typ von v bool ist und boolalpha == 0 , wird verfahren, als ob der Typ von v long wäre, außer für den in Stufe 3 zu speichernden Wert in v .
  • Wenn der Typ von v bool ist und boolalpha ! = 0 , ersetzen die folgenden Schritte die Stufen 2 und 3:
    • Aufeinanderfolgende Zeichen vom Eingabeiterator in werden mit den Zeichensequenzen abgeglichen, die von std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) und std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) stammen, und zwar nur so weit wie nötig, um eine eindeutige Übereinstimmung zu identifizieren. Der Eingabeiterator in wird nur dann mit end verglichen, wenn ein Zeichen benötigt wird.
    • Wenn die Zielsequenz eindeutig übereinstimmt, wird v auf den entsprechenden bool -Wert gesetzt. Andernfalls wird false in v gespeichert und std::ios_base::failbit wird err zugewiesen. Wenn vor Ende der Eingabe ( in == end ) keine eindeutige Übereinstimmung gefunden werden konnte, wird err | = std:: ios_base :: eofbit ausgeführt.

Stufe 2: Zeichenextraktion

  • Wenn in == end , wird Phase 2 sofort beendet, keine weiteren Zeichen werden extrahiert.
  • Das nächste Zeichen wird aus in extrahiert, als ob durch char_type ct = * in ; :
    • Wenn das Zeichen mit einem der "0123456789abcdefxABCDEFX+-" (bis C++11) "0123456789abcdefpxABCDEFPX+-" (seit C++11) übereinstimmt, erweitert auf den char_type des Locales als ob durch std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) . widen ( ) , wird es in das entsprechende char konvertiert.
    • Wenn das Zeichen mit dem Dezimaltrennzeichen ( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) ) ) übereinstimmt, wird es durch '.' ersetzt.
    • Wenn das Zeichen mit dem Tausendertrennzeichen ( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) ) übereinstimmt und die Tausendertrennung aktiv ist (bestimmt durch std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) . length ( ) ! = 0 ), dann wird, wenn der Dezimalpunkt '.' noch nicht akkumuliert wurde, die Position des Zeichens gemerkt, das Zeichen jedoch ansonsten ignoriert. Wenn der Dezimalpunkt bereits akkumuliert wurde, wird das Zeichen verworfen und Phase 2 beendet.
    • In jedem Fall wird geprüft, ob das char aus den vorherigen Schritten im Eingabefeld erlaubt ist, das durch std::scanf geparst würde, gegeben den in Phase 1 ausgewählten Konvertierungsspezifizierer. Wenn es erlaubt ist, wird es in einem temporären Puffer akkumuliert und Phase 2 wiederholt sich. Wenn es nicht erlaubt ist, wird Phase 2 beendet.

Stufe 3: Konvertierung und Speicherung

  • Die in Phase 2 akkumulierte Sequenz von char s wird in einen numerischen Wert umgewandelt:
Die Eingabe wird gemäß den Regeln von std::scanf geparst.
(bis C++11)
Die Eingabe wird geparst als ob durch
(seit C++11)
  • Wenn die Konvertierungsfunktion das gesamte Feld nicht konvertieren kann, wird der Wert 0 in v gespeichert.
  • Wenn der Typ von v ein vorzeichenbehafteter Ganzzahltyp ist und die Konvertierungsfunktion einen positiven oder negativen Wert ergibt, der zu groß ist, um darin gespeichert zu werden, wird der größte positive bzw. negative darstellbare Wert in v gespeichert.
  • Wenn der Typ von v ein vorzeichenloser Ganzzahltyp ist und die Konvertierungsfunktion einen Wert ergibt, der nicht hineinpasst, wird der größte positive darstellbare Wert in v gespeichert.
  • In jedem Fall, wenn die Konvertierungsfunktion fehlschlägt, wird std::ios_base::failbit an err zugewiesen.
  • Andernfalls wird das numerische Ergebnis der Konvertierung in v gespeichert.
    • Wenn der Typ von v bool ist und boolalpha nicht gesetzt ist, dann wird false gespeichert, wenn der zu speichernde Wert 0 ist, und true gespeichert, wenn der zu speichernde Wert 1 ist; für jeden anderen Wert wird std::ios_base::failbit an err zugewiesen und true gespeichert.
  • Danach wird die Zifferngruppierung überprüft. Wenn die Position eines der in Phase 2 verworfenen Tausendertrennzeichen nicht mit der durch std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) bereitgestellten Gruppierung übereinstimmt, wird std::ios_base::failbit an err zugewiesen.
  • Wenn Phase 2 durch den Test in == end beendet wurde, wird err | = std:: ios_base :: eofbit ausgeführt, um das EOF-Bit zu setzen.

Rückgabewert

in

Hinweise

Vor den Lösungen von LWG issue 23 und LWG issue 696 blieb v unverändert, falls ein Fehler auftritt.

Vor der Lösung von LWG issue 221 wurden hexadezimale Ganzzahldarstellungen (z.B. "0xA0" ) von do_get(int) zurückgewiesen, selbst wenn sie gültige Eingaben für strtol darstellten, da Stufe 2 die Zeichen 'X' und 'x' herausfilterte.

Vor der Lösung von LWG issue 1169 konnte die Konvertierung einer negativen Zahlzeichenkette in eine vorzeichenlose Ganzzahl Null ergeben (da der durch die Zeichenkette repräsentierte Wert kleiner ist als der, den der Zieltyp darstellen kann).

Vor der Lösung von LWG Issue 2381 wurden hexadezimale Gleitkommazahlen mit Exponenten (z.B. "0x1.23p-10" ) von do_get(double) zurückgewiesen, selbst wenn sie gültige Eingaben für strtod waren, da Stufe 2 die Zeichen 'P' und 'p' herausfiltert.

Zeichenketten, die Unendlich oder keine Zahl darstellen (z.B. "NaN" und "inf" ), werden von do_get(double) zurückgewiesen, selbst wenn sie gültige Eingaben für strtod sind, da Stufe 2 Zeichen wie 'N' oder 'i' herausfiltert.

(seit C++11)

Beispiel

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

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

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 17 C++98 der Prozess zum Parsen von Text-Booleschen Werten war fehlerhaft korrigiert
LWG 18 C++98 die Überladung von get mit bool & Parameter fehlte hinzugefügt
LWG 23 C++98 überlaufende Eingabe führte zu undefiniertem Verhalten Überlauf behandelt
LWG 154 C++98 der Konvertierungsspezifizierer für double war % g (gleich wie für float ) geändert zu % lg
LWG 221 C++98 do_get parse 'x' und 'X' nicht, während strtol sie parste 'x' und 'X' werden geparst
LWG 275 C++98 get hatte eine Überladung mit short & anstelle von float & korrigiert
LWG 358 C++98 Tausendertrennzeichen nach dem Dezimalpunkt wurden ignoriert Phase 2 wird beendet, wenn sie auftreten
LWG 696 C++98 das Ergebnis blieb bei Konvertierungsfehlern unverändert auf Null gesetzt
LWG 1169 C++98 Überlaufbehandlung war zwischen Gleitkommatypen inkonsistent konsistent gemacht
mit strtof / strtod
LWG 2381 C++11 do_get parse 'p' und 'P' nicht, während strtod sie parste 'p' und 'P' werden geparst

Siehe auch

extrahiert formatierte Daten
(öffentliche Elementfunktion von std::basic_istream<CharT,Traits> )