Zum Inhalt springen

c++ - ungültige eingabe abfangen (int > char)


Harry-Harald

Empfohlene Beiträge

hallo leute,

ich habe gerade ein kleines programm in c++ geschrieben. dabei wird eine variable als int deklariert. der benutzer kann für int einen wert eingeben - mein problem ist, wenn er einen zahl eingibt, ist alles okay. gibt er aber einen buchstaben ein, stürzt das programm ab. ich möchte gerne die ungültige eingabe abfangen, habe aber keine ahnung, wie.

bin für jeden lösungsvorschlag dankbar.

hier noch ein vergleichbarer quelltext:

#include <iostream.h>

int main()

{

int wert;

cout<<"wert eingeben: "<<endl;

cin>>wert; //ein buchstabe...absturz!

cout<<"wert: "<<wert;

//wie fange ich die buchstabeneingabe ab?

return 0;

} :confused:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Versuch doch mal sowas:

#include "stdafx.h"

#include <iostream.h>

int main(int argc, char* argv[])

{

int wert;

while(true) // Endlosschleife um den Effekt zu sehen

{

cout<<"wert eingeben: "<<endl;

try

{

cin>>wert; //ein buchstabe...absturz!

if (!wert) throw"Ein Buchstabe wurde eingegeben";

cout<<"wert: "<<wert;

}

catch (char*Fehlermeldung)

{

cout<<"Error: "<<Fehlermeldung;

return 0;

}

}

}

Vom Studio aus mit Strg-F5 starten, damit das Dos-Fenster geöffnet bleibt und man sich die Fehlermeldung anschauen kann.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Crush:

Das Problem dabei ist allerdings, dass die Exception auch dann geworfen wird, wenn der Benutzer Null eingibt.

@Elmo:

Wenn der Benutzer einen oder mehrere Buchstaben eingibt, bekommt Dein int den Wert 0.

Wenn Null keine gültige Eingabe ist, dann prüf einfach den Wert nach der Eingabe und brich gegebenenfalls ab.

Wenn Null ein erlaubter Wert sein soll, dann liegt der Fehler an einer anderen Stelle in Deinem Programm. Was machst Du mit der eingegebenen Zahl?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi ,

also ich glaube auch das der Programmabsturz ausder falschen Benutzereingabe resultiert, sondern woanders herkommen muß.

Crush:

Also das ist jetzt vielleicht Ansichtssache aber ich finde es ein wenig drastisch auf ein falsche Benutzereingabe programmtechnisch mit einer Exception zu reagieren.

Also um falsche Benutzereingabe zu abzufangen muß nman diese auch prüfen.

Also das einfachste wäre :

Eingabe nicht als Interger sondern als String, Gültigkeit prüfen, dann Umwandeln in Integer.

Natürlich kannst du das ganze auch in eine eigene Klasse kapseln und den Operator >> anders überladen.

Und hier wäre es dann vielleicht auch sinnvoll Eingabefehler über Exceptions abzuhandeln.

Hoagi

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich mal nochmal nachgeschaut.

Der Operator >> entfernt alle führenden Leerzeichen

und liest in der Intvariante dann alle Zeichen

bis er auf ein nicht Interpretierbares Zeichen trifft.

Dann bricht er die Suche ab.

Dabei interpretiert er aber auch solche Sache wie 0xa0

(Hexzahl ).

Findet er nur Whitespaces erwartet er eine Neueingabe.

Ansonsten setzt er die bis dahin gelesenen Zeiche als Zahl um.

Sind nicht nur Whitespaces im String und bringt er die bisdahin gelesenen Zeichen nicht zu einer Zahl zusammen setzt er ein Statusbit das mit der Memberfunktion fail abgefangen werden kann.

also:

cin>>i;

if ( cin.fail() )

{

//Fehler bei Eingabe

}

else

{

//irgendwas interpretierbares gefunden

}

Das Problem liegt in dem irgendwas interpretierbares gefunden

So ist 0xx1 ein Fehler weil beim ersten nicht mehr zu interpretierenden Zeichen ( dem 2. x ) noch nichts sinnvolles bei rausgekommen ist )

während 0x1xx0000sdjslödsöd z.B. eine 1 ergibt,

eben 0x1.

Wenn das reicht kamm man damit arbeiten, ansonsten muß wohl doch selbst Hand anlegen.

Hoagi

Link zu diesem Kommentar
Auf anderen Seiten teilen

Noch einen kleinen Hinweis

Mit der Memberfunktion flags kann auch noch die Interpretation von Zahlen mit ner anderen Basis als 10 abblocken.

Mit

cin.flags( cin.flags() | ios::dec )

setzt man das entsprechende Flag für Dezimalzahl, wass aber das Problem mit dem nach der Zahl kommenden Zeichen aber nicht behebt.

0x1 ergibt dann eben 0.

Hoagi

Link zu diesem Kommentar
Auf anderen Seiten teilen

@hoagi:

Hast Recht, ich finde die Geschichte mit dem Überladen vom Operator auch ganz gut. Etwas eleganter wäre vielleicht auch noch diese Möglichkeit:

Da gibt´s ja auch noch den Checkerr()-Ansatz. Alle Funktionen in eine Klasse Kapseln und sobald ein Fehler aufgetreten ist wird beim Verlassen der Funktion ein entsprechender Errorcode zurückgegeben, welcher sofort abgecheckt wird.

Das kann dann eventuell so aussehen:

Checkerr(myfunk.ZeichenvonTastaturlesen());

Checkerr(myfunk.ZeichenaufWindowausgeben());

Der Fehlerwert wird noch in Checkerr() ausgewertet und dort können dann Ausnahmebehandlungen erfolgen.

Ich habe das bei OCI-Programmierung gelernt und habe das auch sehr schnell "schätzen"-gelernt. Wenn man übersichtlichen Code will, kann man auch so jede Unterfunktion abtasten. (hilft auch prima bei Fehlersuche). Man kann so auch wunderbar Errorlisten zur Laufzeit generieren.

Soweit möglich, sollte man ja auch mit Assert() arbeiten, hier ist jedoch eine Fehlerbehandlung im Programm nicht möglich, ist halt nur für Fehlersuche im Debugger.

<FONT COLOR="#a62a2a" SIZE="1">[ 03. September 2001 00:10: Beitrag 2 mal editiert, zuletzt von Crush ]</font>

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie schon hoagi richtig gesagt hat:

Das ist mal wieder die alte Frage nach der Behandlung von (DAU- ) Benutzereingaben. Einer der erfolgversprechenderen Wege ist, generell in einen String einzulesen mit cin.get() oder cin.getline() (Obacht, eins davon ist in MSVC glaub ich fehlerhaft implementiert, kann man aber sehr leicht nachschreiben :) ).

Dann kann man den String in aller Ruhe wieder und wieder auf sinnvolle/-lose Bestandteile prüfen, und dann verarbeiten oder verwerfen und mit Exceptions werfen.

Was einmal aus dem Eingabepuffer weg ist, ist nun mal weg, und es sehr unschön, mit ungetc() und Konsorten anzufangen. Es sollte nicht vergessen werden, daß die ganze Verarbeitung über cin/cout/cerr weniger zur Interaktion mit Benutzern taugt (ja, schon ein bißchen auch, habe selber keine Probleme mit Kommandozeilen) als vielmehr zur Automatisierung in scripts/pipes (jaja, unix läßt grüßen). Deswegen darf kein Datenverlust auftreten - man kann Fehleingaben immer noch nach cerr schicken und von dort in ein errorlog schreiben, oder so- und der Programmablauf als solcher sollte nicht gefährdet, muß also immer determiniert sein.

cin bietet übrigens jede Menge Statusbits die abgefragt werden können - die Klassen ios und abgeleitete sind zwar sehr umfangreich aber auch sehr mächtig.

Ein anderes Problem ist, daß der ganze Müll, den cin nicht mehr interpretiert, im Eingabepuffer stehenbleibt und dort die weitere Verarbeitung behindert, das heißt, wenn ich den Buchstaben, den cin beim ersten cin>>int nicht wollte, auch bei den darauffolgenden Malen nicht unterkriege...

Der Käptn

<FONT COLOR="#a62a2a" SIZE="1">[ 03. September 2001 13:38: Beitrag 1 mal editiert, zuletzt von captain haddock ]</font>

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...