Bei meinen Versuchen dieser AusdruckWas ist das Ergebnis von `strtod (" 3ex ", & end)? Was ist mit `Sscanf`?
double d = strtod("3ex", &end);
initialisiert d
mit 3.0
und legt end
Zeiger auf 'e'
Zeichen in der Eingabezeichenfolge. Das ist genau so, wie ich es erwarten würde. Das Zeichen 'e'
könnte als Anfang des Exponententeils aussehen, aber da der tatsächliche Exponentenwert (erforderlich nach 6.4.4.2) fehlt, sollte 'e'
als vollständig unabhängiges Zeichen behandelt werden.
Allerdings, wenn ich
double d;
char c;
sscanf("3ex", "%lf%c", &d, &c);
tun merke ich, dass sscanf
sowohl verbraucht '3'
und 'e'
für die %lf
Formatbezeichner. Variable d
empfängt 3.0
Wert. Variable c
endet mit 'x'
darin. Das sieht aus zwei Gründen komisch aus.
Erstens, da die Sprachspezifikation zu strtod
bezieht, wenn das Verhalten von %f
Formatbezeich beschreiben, I erwarteten intuitiv %lf
die Eingabe der gleiche Weise strtod
tut (das heißt wählen, die gleiche Position wie der Abschlusspunkt) zu behandeln. Allerdings weiß ich, dass scanf
historisch nicht mehr als ein Zeichen zurück in den Eingabestream zurückgeben sollte. Das begrenzt die Entfernung eines beliebigen Look-Ahead scanf
um ein Zeichen. Und das obige Beispiel erfordert mindestens zwei Zeichen Vorausschau. Nehmen wir an, ich akzeptiere die Tatsache, dass %lf
sowohl '3'
als auch 'e'
aus dem Eingabestrom verbraucht hat.
Aber dann laufen wir in die zweite Ausgabe. Jetzt muss sscanf
das "3e"
in den Typ double
konvertieren. "3e"
ist keine gültige Darstellung einer Gleitkommakonstante (auch hier ist der Exponentenwert gemäß 6.4.4.2 nicht optional). Ich würde erwarten, sscanf
diesen Eingang als fehlerhaft zu behandeln: Beenden Sie während der %lf
Konvertierung, geben Sie 0
zurück und lassen Sie d
und c
unverändert. Das obige sscanf
wird jedoch erfolgreich abgeschlossen (2
wird zurückgegeben).
Dieses Verhalten ist konsistent zwischen GCC- und MSVC-Implementierungen der Standardbibliothek.
Also, meine Frage ist, wo genau in der Sprache C Standard-Dokument erlaubt es sscanf
wie oben beschrieben zu verhalten, zu den beiden oben genannten Punkte beziehen: Verbrauch von mehr als strtod
tut und erfolgreich solche Sequenzen als "3e"
Umwandlung?
Wenn ich mir meine Testergebnisse anschaue, kann ich wahrscheinlich das Verhalten von sscanf
"reverse engineeren": konsumiere so viel wie "sieht richtig aus" gehe nie zurück und gebe dann die verbrauchte Sequenz einfach an strtod
weiter. Auf diese Weise wird 'e'
von %lf
verbraucht und dann einfach von strtod
ignoriert. Aber war genau das alles in der Sprachspezifikation?
Vielleicht liegt der Grund (obwohl keine gute Ausrede) für den Unterschied in der Tatsache, dass "sscanf" in "stdio" und "strtod" in "stdlib" steht. –
Nicht wirklich sicher, ich verstehe: Warum scheint das Ergebnis von sscanf Ihnen fremd zu sein? Was genau hast du erwartet? Könnten Sie bitte ein bisschen mehr Details geben? – HighPredator
@HighPredator: OP bedeutet wahrscheinlich, dass die Variable "c" den Wert "e" und nicht den Wert "x" erreichen soll. Oder vielleicht sollte es überhaupt keinen Wert erreichen, und die Funktion 'sscanf' sollte 1 statt 2 zurückgeben (so emuliert es genau das Verhalten von' strtod'). –