| Autor |
Beitrag |
Zappt
      
Beiträge: 18
|
Verfasst: 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 Narses: Topic aus Sonstiges (Delphi) verschoben am So 07.06.2009 um 13:54
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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
      
Beiträge: 573
WIN XP/2000 & 7Prof (Familie:Win95,Win98)
|
Verfasst: Sa 06.06.09 19:05
Versuchst Du das Eingegebene direkt mit StrToInt zu parsen?
Dann solltest Du doch lieber erst mal mit Delphi-Quelltext 1: 2: 3: 4:
| if isInt(TexfeldWert.Text) then else 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 07.06.09 10:15
delfiphan hat folgendes geschrieben : | | 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: So 07.06.09 10:32
delfiphan hat folgendes geschrieben : | | 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 07.06.09 10:54
Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden.
_________________ Markus Kinzler.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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...
Yogu hat folgendes geschrieben : | | 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...
mkinzler hat folgendes geschrieben : | | 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 07.06.09 11:48
Aber auch dann würde ich nicht mit Exceptions arbeiten
_________________ Markus Kinzler.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 07.06.09 12:00
mkinzler hat folgendes geschrieben : | | 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 
      
Beiträge: 18
|
Verfasst: So 07.06.09 14:31
Gibts euch auch für Anfänger?
Ein Beispiel:
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 Narses: Delphi-Tags hinzugefügt
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 07.06.09 14:34
_________________ Markus Kinzler.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 07.06.09 14:37
_________________ 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
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: So 07.06.09 18:07
delfiphan hat folgendes geschrieben : | | 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.
delfiphan hat folgendes geschrieben : | | Wie auch immer, das jetzt eher eine philosophische Frage, wo man noch lange Diskussionen darüber führen kann... |
Na denn mal los
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
mkinzler hat folgendes geschrieben : | | Aber eine Falscheingabe des Anwenders sollte nicht mit einer Exception quittiert werden. |
... und genau dafür ist ja TryStrToInt.
delfiphan hat folgendes geschrieben : | | [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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 07.06.09 21:01
Yogu hat folgendes geschrieben : | Aber jetzt schreib mal eine allgemeine Fehlerbehandlung für eine Zugriffsverletzung  |
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.
|
|