Autor Beitrag
Zappt
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Sa 06.06.09 18:58 
Hey wenn ich in ein Feld nen Buchstabe eingeben statt ne Zahl stürtz das Programm ab. Warum ist mir klar aber WIE verhindert man das Abstürzen?

Lg,
Zappt


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am So 07.06.2009 um 13:54
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 06.06.09 19:04 
1. Nur Zahlen, Komma und Zurücktaste zulassen
2. Eingabe mit TryStrToInt() oder StrToIntDef() überprüfen.

Beispiele dazu findest Du hier im Forum. ;)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.06.09 19:04 
TryStrToInt, bzw. Überprüfen, ob es wirklich eine Zahl im Edit ist.

Außerdem: Da stürzt das Programm nicht ab, sondern wirft eine Exception. Je nach dem, was man da falsch gemacht hat, kann sich das Programm da durchaus noch selber wieder fangen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
ffgorcky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 573

WIN XP/2000 & 7Prof (Familie:Win95,Win98)

BeitragVerfasst: Sa 06.06.09 19:05 
Versuchst Du das Eingegebene direkt mit StrToInt zu parsen?
Dann solltest Du doch lieber erst mal mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
if isInt(TexfeldWert.Text) then
//Und hier dann Deine Berechnungs-Anweisung
else //wenn das dann doch keine (ganze) Zahl ist:
   Application.MessageBox('Es ist leider ein Fehler bei der Zahlen-Umwandlung aufgetreten!'+#13#10+'Hier dürfen nur (ganze) Zahlen eingetragen werden!','',MB_OK + MB_ICONERROR);
fragen, ob diese beiden denn wirklich Zahlen sind!
Das isInt wäre zum Beispiel hier im 5. Beitrag (also dem von mir) erhältlich!

Du könntest natürlich auch nach diesen Beitrag mit TryStrToInt('0', i): Boolean umsetzen
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 09:51 
Der User macht einen Fehler und kriegt eine Fehlermeldung. Ist doch eigentlich gut, oder? Wenn dir das nicht gefällt, was ist das gewünschte Verhalten?
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 07.06.09 10:15 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Der User macht einen Fehler und kriegt eine Fehlermeldung. Ist doch eigentlich gut, oder? Wenn dir das nicht gefällt, was ist das gewünschte Verhalten?

Das Programm bricht dann aber mit einer Exception ab und das ist nicht in Ordnung. Deshalb muss du als Programmierer solche Falscheingaben abfangen und ggf. den Anwender dafür tadeln.

_________________
Markus Kinzler.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 10:27 
Das Programm bricht nicht ab, sondern arbeitet die Exception Chain ab. Ohne speziellen Exception-Handler gelangt das bei einer einfachen GUI-VCL-Applikationen in den Exception-Handler der Hauptschleife, und der zeigt die Exception einfach als MessageBox an. Danach geht es weiter mit der Hauptschleife, als ob nichts gewesen wäre...
Die Exception-Fehlermeldung sagt dem Benutzer schon was er falsch gemacht hat. Eventuell kann man die Fehlermeldung noch ausschmücken, das fehlerhafte Feld irgendwie markieren und so weiter, aber sonst seh ich jetzt nicht, was das Problem dabei ist.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 07.06.09 10:32 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Der User macht einen Fehler und kriegt eine Fehlermeldung. Ist doch eigentlich gut, oder? Wenn dir das nicht gefällt, was ist das gewünschte Verhalten?

Professionelle Software behandelt Exceptions, die im Programm selber nicht abgefangen werden, normalerweise mit einem Programmabsturz. Denn dann ist klar, dass das Programm einen Bug enthält, und dass der momentane Status der Anwendung nun vollkommen undefiniert ist - theoretisch (!) könnten Dateien gelöscht werden etc., und das soll verhindert werden.

Microsoft bringt dann die berühmt-berüchtigte Meldung "Fehlerbericht senden?", der Firefox öffnet ein ähnliches Fenster. Und für Delphi gibt's so Sachen wie madExcept. Deshalb: Vorhersehbare Ausnahmen immer abfangen und mit einem einfachen Dialog anzeigen.
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 07.06.09 10:54 
Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden.

_________________
Markus Kinzler.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 11:22 
Ich bin nur teilweise einverstanden, was den sofortigen Absturz, die vollkommene Undefiniertheit und professionelle Software betrifft.

Theoretisch mag das schön sein, aber wenn man sich auf externe Libraries verlassen muss (wo man nicht alle Details kennen kann oder tut) und sich der Tatsache bewusst ist, dass es nun mal praktisch keine bugfreie Software gibt, dann weiss ich nicht ob das die beste Lösung ist, das Programm einfach abstürzen zu lassen. Vollkommene Undefiniertheit kann verhindert werden, wenn man möglichst so programmiert, dass bei Exceptions alle Aktionen rollbacked und die Exception reraised wird bzw. nicht committed sind. Eine Exception muss nicht dazu führen, dass die Applikation in einem inkonsistenten Zustand ist (auch bei nicht vorhersehbaren Exceptions).

Beispiel: Bei einem Webserver ist es okay, einen pauschalen "top-level" Exception-Handler zu haben, der eine HTTP 500 Internal Server Error zurückgibt. Ein sofortiger Absturz nützt hier niemandem was.

Wie auch immer, das jetzt eher eine philosophische Frage, wo man noch lange Diskussionen darüber führen kann...

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Microsoft bringt dann die berühmt-berüchtigte Meldung "Fehlerbericht senden?"
Diese Meldung kann soweit ich weiss bei jedem Programm auftreten. Das ist wohl einfach der top-level Exception Handler von Windows, der den Hauptthread wrappt...

user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden.
Die Falscheingabe wird nicht mit der Exception quittiert, sondern mit einer Fehlermeldung in einem Fenster, der durch den Exception-Handler von Delphi angezeigt wird...
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 07.06.09 11:34 
Zitat:
user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden.
Die Falscheingabe wird nicht mit der Exception quittiert, sondern mit einer Fehlermeldung in einem Fenster, der durch den Exception-Handler von Delphi angezeigt wird...

Das hatte ich verkürzt gemeint. Man sollte entweder die Falscheingabe abfangen oder verhindern, in dem man nur gültige Zeichen zulässt

_________________
Markus Kinzler.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 11:44 
Verhindern ist nicht immer möglich, da bei gewissen Datentypen zuerst was Falsches eingegeben werden muss, bevor was Korrektes dasteht. Beispiel Integer: "-5", wobei "-" kein Integer ist. Oder, bei Floats: "1e-5". Auch, wenn man dann z.B. ab "e" alles mit der Delete-Taste wieder löschen will, wird aus "1e-5" zuerst "1-5".

Beim Abfangen von falschen Tasten muss man noch berücksichtigen, dass man Copy&Paste verwenden kann.

Falsche Felder zu markieren ist eine einfache und gute Möglichkeit.
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 07.06.09 11:48 
Aber auch dann würde ich nicht mit Exceptions arbeiten

_________________
Markus Kinzler.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 12:00 
user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
Aber auch dann würde ich nicht mit Exceptions arbeiten
Eine Möglichkeit wäre es, Edit-Felder zu konstruieren, die eine Validate Methode oder ein OnValidate-Event haben. Das Feld würde sich dann rot einfärben, wenn der Inhalt nicht korrekt ist. Der "Ok" Knopf des Formulars wäre erst dann enabled, sobald alle Felder valid sind.

Wie Validate bzw. OnValidate implementiert ist, ist erst mal nebensächlich, aber ich geb dir recht, eine (auch wenn gehandelte) Exception in einer Validate-Methode fände ich jetzt nicht so schön.

[OT]Bei einer Datenbankkomponente wurde intern viel mit Exceptions gearbeitet. Bei jedem Query gab's intern eine Exception, die auch intern wieder gehandelt wurde. Von aussen merkte man nichts, aber man musste jeweils immer in der IDE die Meldung für gewisse Exception-Klassen ausschalten. Das war lästig... Ausserdem hatte ich dann einige Exceptions abgestellt, wo ich eine Meldung gerne gehabt hätte...[/OT]
Zappt Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: So 07.06.09 14:31 
Gibts euch auch für Anfänger? :D
Ein Beispiel:
ausblenden Delphi-Quelltext
1:
2:
test:real;
test:=strtofloat(edit7.text);

Wo hau ich jetzt den befehl "try" rein?

Danke
Zappt

Ps:Oder wie mach ich es das man ins Feld nur Zahlen eingeben darf? Das würde mein Problem schon lösen!

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 07.06.09 14:34 
ausblenden Delphi-Quelltext
1:
if not TryStrToFloat(edit7.text, test) then //Falsche Eingabe					


oder

ausblenden Delphi-Quelltext
1:
test := StrToFloatDef( Edit7.Text, 1); // Bei falscher Eingabe hat Test dann den Defaultwert 1					

_________________
Markus Kinzler.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 07.06.09 14:37 
user profile iconZappt hat folgendes geschrieben Zum zitierten Posting springen:
Gibts euch auch für Anfänger? :D

Ja, aber nur mit Aufpreis :mrgreen:

Für den Rest verweise ich auf das Posting über mir von user profile iconmkinzler

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 07.06.09 18:07 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Beispiel: Bei einem Webserver ist es okay, einen pauschalen "top-level" Exception-Handler zu haben, der eine HTTP 500 Internal Server Error zurückgibt. Ein sofortiger Absturz nützt hier niemandem was.

Das ist klar, dort bringt auch die schönste Fehlermeldung auf dem Server-Rechner nichts. Server sind eine Ausnahme, aber sonst sollte immer der Client benachrichtigt werden, sofern keine Behandlung möglich ist.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Wie auch immer, das jetzt eher eine philosophische Frage, wo man noch lange Diskussionen darüber führen kann...

Na denn mal los :mrgreen:

An manchen Stellen ist es wirklich einfach, ein kurzes Roll-back zu machen - das passiert ja auch bei Konstruktoren etc. Meine Anwendungen haben zum Beispiel für jede Datei ein TabSheet, und wenn bei dessen Erstellen ein Fehler auftritt, wird das TabSheet einfach wieder geschlossen. (natürlich nachdem der Benutzer benachrichtig wurde). Aber jetzt schreib mal eine allgemeine Fehlerbehandlung für eine Zugriffsverletzung :P

user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden.

... und genau dafür ist ja TryStrToInt.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
[OT]Bei einer Datenbankkomponente wurde intern viel mit Exceptions gearbeitet. Bei jedem Query gab's intern eine Exception, die auch intern wieder gehandelt wurde. Von aussen merkte man nichts, aber man musste jeweils immer in der IDE die Meldung für gewisse Exception-Klassen ausschalten. Das war lästig... Ausserdem hatte ich dann einige Exceptions abgestellt, wo ich eine Meldung gerne gehabt hätte...[/OT]

Die Indys schmeißen auch immer eine EIdConnectionClosedGracefully, wenn die Verbindung beendet wurde. Und standardmäßig sind einige Exceptions eingetragen, bei denen der Debugger nicht anhält - in begrenztem Maße ist das ok.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.06.09 21:01 
user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Aber jetzt schreib mal eine allgemeine Fehlerbehandlung für eine Zugriffsverletzung :P

Das geht vielleicht nicht direkt, trotzdem kannst du im Idealfall alles rückgängig machen, sodass der Stand vor der fehlerhaften Aktion wiederhergestellt ist (siehe en.wikipedia.org/wiki/Abrahams_guarantees). Meinetwegen kann man dann die Fehlermeldung "Aktion konnte nicht ausgeführt werden" ausgeben. Ist immer noch besser, als wenn der Benutzer eine Stunde an einem Dokument gearbeitet hat und sich das Word einfach schliesst, nur weil ein nicht vorhergesehener Fehler aufgetreten ist... Und da man bei sehr grossen Projekten einfach nicht an alles denken kann, und weil Programme nie bugfrei sind, halte ich das Schliessen des Programmes für die falsche Lösung. Aber für weitere Diskussionen ist das hier bestimmt der falsche Thread.