3 Stimmen

Sollte C++ Variablen bei Eingabefehler intakt halten?

Bietet C++ keine Garantie dafür, dass Variablen bei Eingabefehlern intakt bleiben? Mit älteren Versionen von gcc behält ein Programm wie dieses den Wert -1 von i bei einem Fehler (zum Beispiel, wenn anstelle einer Zahl ein Buchstabe eingegeben wird). Mit Ubuntu 10.10 (gcc 4.4.5) wird i bei einem Eingabefehler auf Null zurückgesetzt.

#include 

int main()
{
 int i = -1;
 std::cin >> i;
 std::cout << "i = " << i << '\n';
 return 0;
}

Dieses Verhalten führt zu Problemen in meinem Code. Ich gehe davon aus, dass die gcc-Entwickler wissen, was sie tun, und es wahrscheinlich mein Fehler ist. Wenn jemand den Standard kennt, würde ich gerne wissen, was er über diese Situation sagt.

Vielen Dank.

5voto

KeatsPeeks Punkte 18568

Verlassen Sie sich nicht auf die Variable. Verlassen Sie sich auf den Zustand des Streams:

if (std::cin >> i) // "if (!std::cin.fail())" würde auch funktionieren
{
    // ok
}
else
{
    // Fehler
}

Was die Änderung des Verhaltens betrifft, liegt das daran, dass sich der C++-Standard weiterentwickelt hat:

Aus C++03:

Wenn ein Fehler auftritt, wird val nicht verändert; andernfalls wird es auf den resultierenden Wert gesetzt.

Aus C++0x (nun ja.. aus dem letzten Entwurf, zu dem ich Zugang habe):

Der numerische Wert, der gespeichert werden soll, kann einer der folgenden sein:

  • null, wenn die Konvertierungsfunktion das gesamte Feld nicht konvertieren kann.
  • der am positivsten (oder negativsten) darstellbare Wert, wenn das Feld, das in einen vorzeichenbehafteten Integer-Typ konvertiert werden soll, einen zu großen positiven (oder negativen) Wert darstellt, um in val dargestellt zu werden.
  • der am positivsten darstellbare Wert, wenn das Feld, das in einen vorzeichenlosen Integer-Typ konvertiert werden soll, einen Wert darstellt, der in val nicht dargestellt werden kann.
  • der konvertierte Wert, sonst.

3voto

Der C++-Standard hat sich hinsichtlich des geforderten Verhaltens für diesen Fall geändert. Die Anforderungen können in [lib.facet.num.get.virtuals] (22.2.2.1.2 in C++03, 22.4.2.1.2 in C++0x) gefunden werden.

In C++03 lautet die Anforderung, dass der alte Wert bei einem Fehler unverändert bleibt.
In C++0x lautet die Anforderung, dass der Wert 0 im Falle eines Konvertierungsfehlers gespeichert wird.

1voto

CashCow Punkte 29849

Wenn Sie möchten, dass ein fehlgeschlagener Stream-In-Vorgang Ihre Variable nicht beeinflusst und Sie nicht möchten, dass der Stream in einen fehlerhaften Zustand versetzt wird, streamen Sie stattdessen in einen String, analysieren Sie den String in ein temporäres Objekt ein und setzen Sie den Vorgang nur fort, wenn alles erfolgreich war.

Sie können den String mit dem istringstream in ein temporäres Objekt analysieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X