Mit istream >> double extrahierte Zeichen

Beispielcodebei Coliru:

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    double d; std::string s;

    std::istringstream iss("234cdefipxngh");
    iss >> d;
    iss.clear();
    iss >> s;
    std::cout << d << ", '" << s << "'\n";
}

Ich lese hier N3337 vor (vermutlich das gleiche wie in C ++ 11). In [istream.formatted.arithmetic] haben wir (umschrieben):

operator>>(double& val);

Wie bei den Insertern hängen diese Extraktoren vom num_get <> (22.4.2.1) -Objekt des Gebietsschemas ab, um das Parsen der Eingabestreamdaten durchzuführen. Diese Extraktoren verhalten sich wie formatierte Eingabefunktionen (wie in 27.7.2.2.1 beschrieben). Nachdem ein Wachobjekt erstellt wurde, wird die Konvertierung so ausgeführt, als ob sie von dem folgenden Codefragment ausgeführt würde:

typedef num_get< charT,istreambuf_iterator<charT,traits> > numget;
iostate err = iostate::goodbit;
use_facet< numget >(loc).get(*this, 0, *this, err, val);
setstate(err);

Mit Blick auf 22.4.2.1:

Die Details dieser Operation erfolgen in drei Schritten
- Stufe 1: Bestimmen eines Konvertierungsspezifizierers
- Stufe 2: Extrahieren Sie Zeichen aus in und bestimmen Sie einen entsprechenden Zeichenwert für das Format, das von der in Stufe 1 bestimmten Konvertierungsspezifikation erwartet wird.
- Stufe 3: Ergebnisse speichern

In der Beschreibung von Stufe 2 ist es zu lang, um das Ganze hier einzufügen. Es ist jedoch klar, dass alle Zeichen extrahiert werden sollten, bevor eine Konvertierung versucht wird. und außerdem sollten genau die folgenden Zeichen extrahiert werden:

irgendein von0123456789abcdefxABCDEFX+-Das Gebietsschemadecimal_point()Das Gebietsschemathousands_sep()

Schließlich enthalten die Regeln für Stufe 3:

- Für einen Gleitkommawert die Funktionstrtold.

Der zu speichernde numerische Wert kann einer der folgenden sein:

- Null, wenn die Konvertierungsfunktion das gesamte Feld nicht konvertieren kann.

Dies alles scheint klar anzugeben, dass die Ausgabe meines Codes sein sollte0, 'ipxngh'. Es gibt jedoch tatsächlich etwas anderes aus.

Ist das ein Compiler- / Bibliotheksfehler? Gibt es eine Bestimmung, die ich für ein Gebietsschema übersehen habe, um das Verhalten von Phase 2 zu ändern? (Imeine andere Frage jemand hat ein Beispiel für ein System gepostet, das die Zeichen tatsächlich extrahiert, aber auch extrahiertipxn die nicht in der in N3337 genannten Liste enthalten sind).

Aktualisieren

Wie von perreal hervorgehoben, ist dieser Text aus Stufe 2 relevant:

Wenn "Verwerfen" wahr ist, wird die Position des Zeichens gespeichert, wenn "." Noch nicht akkumuliert wurde, ansonsten wird das Zeichen ignoriert. Andernfalls wird das Zeichen verworfen und Stufe 2 wird beendet, wenn bereits. Angesammelt wurde. Wenn es nicht verworfen wird, wird geprüft, obc ist als nächstes Zeichen eines Eingabefelds des von Stufe 1 zurückgegebenen Konvertierungsspezifizierers zulässig. Wenn ja, wird es akkumuliert.

Wenn das Zeichen entweder verworfen oder akkumuliert ist, wird in um ++ in vorgerückt und die Verarbeitung kehrt zum Anfang von Stufe 2 zurück.

Daher kann Stufe 2 beendet werden, wenn das Zeichen in der Liste der zulässigen Zeichen enthalten ist, jedoch kein gültiges Zeichen für ist%g. Es sagt nicht genau, aber vermutlich bezieht sich dies auf die Definition vonfscanf ab C99, was ermöglicht:

eine nicht leere Folge von Dezimalstellen, die optional ein Dezimalzeichen und anschließend einen optionalen Exponententeil gemäß 6.4.4.2 enthält;ein 0x oder 0X, dann eine nicht leere Folge von Hexadezimalziffern, die optional ein Dezimalzeichen enthält, dann ein optionaler binärer Exponententeil, wie in 6.4.4.2 definiert;INF oder INFINITY, Groß- / Kleinschreibung ignorierenNAN oder NAN (n-char-sequence opt), Groß- und Kleinschreibung im NAN-Teil ignorierend, wobei:

und auch

In anderen als dem "C" -Gebietsschema können zusätzliche länderspezifische Subjektsequenzformen akzeptiert werden.

Tatsächlich ist die Coliru-Ausgabe also korrekt. und in der Tat die VerarbeitungMuss Versuchen Sie, die Zeichenfolge zu validieren, die bisher als gültige Eingabe für extrahiert wurde%g, während jedes Zeichen extrahiert wird.

Nächste Frage: Ist es erlaubt, wie in dem Thread, den ich zuvor verlinkt habe, zu akzeptiereni , n, p usw. in Stufe 2?

Dies sind gültige Zeichen für%g sie befinden sich jedoch nicht in der Liste der Atome, die Stufe 2 lesen darf (d. h.c == 0 für mein letztes Zitat wird das Zeichen also weder verworfen noch akkumuliert).

Antworten auf die Frage(2)

Ihre Antwort auf die Frage