Entwickler-Ecke
Sonstiges (Delphi) - String in Zahl umwandeln - OHNE Exception?
tempuss13 - Mi 24.02.10 22:45
Titel: String in Zahl umwandeln - OHNE Exception?
Hallo Delphi-Freunde!
Hab so einiges versucht, hänge hier fest.
Ich lese aus einer Datei div. Zeilen ein, hier sind Text und Datum(in Stringformat) abgelegt.
Wenn ich den 2-stelligen String in die entspr. Tageszahl umwandle, knallt mir immer eine Exception auf den Bildschirm.
In ca. 5 Fäleen von knapp 100 Zeilen steht, wo das Tages-Datum stehen sollte, z.B. <li>, wie auch immer das in die Datei gelangt.
Ich will solche Fehler abfangen, aber WIE???
Mit try und except klappt das nicht! Müsste ich noch einen Compilerschalter nutzen? Z.B. {$V-}?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.Button1Click(Sender: TObject); var done: boolean; i: integer; Dummy: string; begin repeat done := true; try for i := 0 to 780 do if strToInt(day[i]) > strToInt(day[i+1]) then begin Dummy := day[i]; day[i] := day[i+1]; day[i+1] := Dummy; done := false; end; except showmessage('KEINE Zahl!'); end; until done; end; |
Alles klappt bestens, bis der Tag mit <li> kommt(bei ca. 300. Zeile).
Unter TP hab ich solche Probs nicht so in Erinnerung.
Für den richtigen Tip/Trick wäre ich wirklich dankbar!
Gruß Uli
der organist - Mi 24.02.10 22:51
versuch mal was mit StrToIntDef, da kannst du noch nen Parameter angeben, der zurückgegeben wird, wenns nen Fehler gibt. Wenn du da z.B -1 nimmst und dann auf -1 abfragst, weisst du, ob es gelaufen is oder nich. Zum andern gibts da imho noch Funktionen wie StrToInfExecpt, schlag mich nich, iwas gabs da, schau mal im Forum...........................................................
Delete - Mi 24.02.10 22:55
tempuss13 hat folgendes geschrieben : |
Mit try und except klappt das nicht! |
Wahnsinns Fehlerbeschreibung.
tempuss13 - Mi 24.02.10 23:15
Danke Dir erstmal!
Zwar erhalte ich mit mit StrToIntDef keine Fehlermeldung, dafür kommen astronomische Zahlen raus..
Ich versuche es eben weiter.
...
Was soll ich zu dem Fehler schreiben?
Es kommt eine Box mit 'Exception'.
Habe einen Screenshot davon als Datei angehängt.
Delete - Mi 24.02.10 23:24
Dann starte die Exe mal nicht aus der IDE.
Und hättest du das gleich gesagt, dann hätte man dich gleich darauf hinweisen können.
Xentar - Mi 24.02.10 23:25
Hast du mal in den Eingangswerten geschaut, ob da nicht doch li drin steht?
Ansonsten: Das ist nur eine Delphi Exception, start das Programm mal aus dem Explorer, dann taucht die nicht auf.
Chemiker - Mi 24.02.10 23:32
Hallo tempuss13,
ich habe Deine Frage nicht so ganz verstanden, aber vielleicht funktioniert Dein Vorhaben mit:
Delphi-Quelltext
1: 2:
| TryStrToFloat(Text, Zahl) TryStrToDate(Text,Datum) |
Bis bald Chemiker
tempuss13 - Mi 24.02.10 23:32
Hallo Luckie!
Ich denke wohl nicht so weit, um gleich alle interressanten Fakten aufzulisten.
Habe eben in der Exceptionenbox einen Haken gesetzt, unter:
"Diesen Fehler ignorieren"
Nun klappt es zwar, kein Absturz und der Exceptionblock wird abgearbeitet.
Aber das ist doch sicher keine saubere Lösung, oder?
In meinem Delphi-Buch steht ausdrücklich drin, dass bei Fehlern der Except-Block abgearbeitet wird.
Doch der wird garnicht erreicht.
Danke Dir!!!
Delete - Mi 24.02.10 23:47
tempuss13 hat folgendes geschrieben : |
Nun klappt es zwar, kein Absturz und der Exceptionblock wird abgearbeitet. |
Zitat: |
Doch der wird garnicht erreicht. |
Du widersprichst dir.
tempuss13 - Mi 24.02.10 23:54
Hallo Chemiker!
Was es alles für Befehle gibt!?
Habe 3 Delphi Bücher, in KEINEM steht sowas drin- traurig!
Auf jeden Fall versuche ich es damit auch noch.
Kann dabei ja nur lernen.
Alte TP-Bücher zeigen alle Befehle in Listenform oder ähnlich an.
Warum gibt es sowas nicht für Delphi??
Die Delphi-Bücher zeigen eher Beispiele auf,
doch fehlt so was wie eine Legende, ein Buch mit allen Delphi-Befehlen.
Vielleicht stelle ich mir das zu einfach vor.
Gruß Uli
---
Moderiert von
Narses: Beiträge zusammengefasst---
Luckie BITTE!
Der Block wurde nicht erreicht, als ich den Ignorieren-Haken in der Exception-Meldung noch nicht gesetzt hatte!
Jetzt ist der Haken GESETZT!
Und jetzt wird der except-Block ABGEARBEITET!
Xentar - Do 25.02.10 00:02
Der Except Block wurde vorher auch abgearbeitet.. aber wenn man sein Programm aus Delphi heraus ausführt, hält Delphi trotzdem an.
tempuss13 - Do 25.02.10 00:05
Das ist auf jeden Fall ein wertvoller Hinweis!!!
Warum steht das in meinem Buch nicht drin??
DANKE Dir!
platzwart - Do 25.02.10 00:06
ALLE Delphi-Befehle??? Dann könntest du dir einen ganzen Aktenschrank anschaffen, nur um eine Auflistung unter zu bekommen.
Und die Exeption, die du gesehen hast, wird lediglich von der IDE ausgelöst bzw. dort angezeigt, um dir als Entwickler einen Hinweis zu geben. Du sollst nicht das Häkchen setzen, sondern die EXE aus dem Explorer heraus starten...
tempuss13 - Do 25.02.10 00:21
Nacheinander:
Wie ich schon schrieb: stelle mir das wohl zu einfach vor.
Und dass nur die IDE den Fehler zeigt, für den Programmierer und als Exe nicht, das wusste ich nicht.
In TP habe ich wirklich Erfahrung sammeln können.
Doch über Delphi muss ich ich noch viel lernen!
Das Buch, dass ich habe heißt: "Delphi 6 in Team"
DANKE Euch allen!
Gammatester - Do 25.02.10 00:24
Xentar hat folgendes geschrieben : |
Der Except Block wurde vorher auch abgearbeitet.. |
Bei Floatingpoint-Exceptions wäre ich vorsichtig mit solchen Behauptungen, wenn ich das nicht selbst gesehen habe. Manche FPU-Exeptions werden, erst beim nächsten FPU-Befehl ausgelöst, und das kann uU meilenweit außerhalb des try except sein.
@tempuss13: wenn's mit TP geklappt, kannst Du ja auch unter Delphi
Val(S; var V; var Code: Integer); benutzen und Code auswerten (hat allerdings den Nachteil, daß das Dezimaldings immer ein '.' ist).
Moderiert von
Narses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
Xentar - Do 25.02.10 10:27
Gammatester hat folgendes geschrieben : |
Xentar hat folgendes geschrieben : | Der Except Block wurde vorher auch abgearbeitet.. |
Bei Floatingpoint-Exceptions wäre ich vorsichtig mit solchen Behauptungen, wenn ich das nicht selbst gesehen habe. Manche FPU-Exeptions werden, erst beim nächsten FPU-Befehl ausgelöst, und das kann uU meilenweit außerhalb des try except sein. |
Ist mir bisher nicht (bewusst) untergekommen.
Über ein Beispiel würde ich mich freuen.
Gammatester - Do 25.02.10 14:44
Xentar hat folgendes geschrieben : |
Gammatester hat folgendes geschrieben : | Xentar hat folgendes geschrieben : | Der Except Block wurde vorher auch abgearbeitet.. |
Bei Floatingpoint-Exceptions wäre ich vorsichtig mit solchen Behauptungen, wenn ich das nicht selbst gesehen habe. Manche FPU-Exeptions werden, erst beim nächsten FPU-Befehl ausgelöst, und das kann uU meilenweit außerhalb des try except sein. |
Ist mir bisher nicht (bewusst) untergekommen.
Über ein Beispiel würde ich mich freuen. |
Ein Beispiel, zwar nicht inhaltlich besonders interessant aber reproduzierbar für Delphi 5-7, Win98 und/oder XP:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
{$ifdef VER130} const Nan = 0/0; {$endif}
procedure TForm1.Button2Click(Sender: TObject); begin Button2.Caption := FloatToStr(random); end;
procedure TForm1.Button1Click(Sender: TObject); var x: extended; begin x := Nan; try if x<>x then Button1.Caption := 'x<>x'; except Button1.Caption := 'Except'; end; end;
end. |
Die Applikation ist ein Form mit 2 Buttons. Drückt man Button1 einmal, scheint sich nichts zu ändern, drückt man dann Button2 gibts eine "Invalid Floating point exception". Drückt man Button1 zweimal ändert sich Button1.caption zu 'Except'. Allgemein (aber nicht immer): Drückt man Button1 ein ungerade Zahl, dann Button2 gibts die Exception, bei gerader Anzahl nicht und Button2.caption zeigt eine neue Zufallszahl.
trm - Do 25.02.10 17:35
Hallo tempuss13,
wenn Du wirklich eine exeptionfreie Alternative suchst, rate ich Dir (weil ich das Problem kenne), den String, der zu überprüfen ist, Char für Char durchgehst und das Zeichen auf eine ziffer testest. Somit brauchst Du noch nicht einmal einen Try..Except - Block :)
Wer ASM gut kann, der könnte ja mal ein ASM-Beispiel mit Registern (?) posten. Würde mich auch interessieren.
Hier die NORMALE Vorgehensweise, welche in der IDE eine Schutzverletzung erzeugt, wenn es sich nicht um eine reine Zahlenfolge im String handelt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| function Test_Integer(Dummy: string): Boolean; begin
Result := False; if Length(Dummy) < 1 then Exit; try StrToInt(Dummy); except Exit; end; Result:=True;
end; |
Hier die Version, welche Char für Char prüft und bei INTEGER-Werten 100% keine Exeption auslöst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function TForm1.Test_Integer2(Dummy: string): Boolean; var x: Integer; begin
Result := False; if Length(Dummy) < 1 then Exit;
for x := 1 to Length(Dummy) do if not (ORD(Dummy[x]) in [48..57]) then Exit;
Result := True;
end; |
Gruß
~Mathias
Edit: Syntaxfehler bei for x := 1 to Length(Dummy) do (war for x:=0 vorher)
SvenAbeln - Do 25.02.10 18:00
trm hat folgendes geschrieben : |
wenn Du wirklich eine exeptionfreie Alternative suchst, rate ich Dir (weil ich das Problem kenne), den String, der zu überprüfen ist, Char für Char durchgehst und das Zeichen auf eine ziffer testest. Somit brauchst Du noch nicht einmal einen Try..Except - Block :)
|
Oder man verwendet einfach
TryStrToInt
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); var Zahl: integer; begin if TryStrToInt(Edit1.Text, Zahl) then begin end else showmessage('Error: Bitte eine Zahl eingeben'); end; |
Chemiker - Do 25.02.10 20:31
Hallo,
hier ein Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
| unit DEMO_String_umwandeln;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TfrmDemoStringUmwandeln = class(TForm) edStringEingabe: TEdit; btStringUmwandeln: TButton; edStringAusgabe: TEdit; procedure btStringUmwandelnClick(Sender: TObject); private public end;
var frmDemoStringUmwandeln: TfrmDemoStringUmwandeln;
implementation
{$R *.dfm}
procedure TfrmDemoStringUmwandeln.btStringUmwandelnClick(Sender: TObject); var strString: String; intZahl: integer; dbZahl: double; dtDatum: TDateTime; begin strString:= edStringEingabe.Text; if TryStrToInt(strString, intZahl) then begin intZahl:= intZahl+2; edStringAusgabe.Text:= inttostr(intZahl); end else begin if TryStrToFloat(strString, dbZahl) then begin dbZahl:= dbZahl+ 44.01; edStringAusgabe.Text:= floattostr(dbZahl); end else begin if TryStrToDate(strString, dtDatum) then begin dtDatum:= dtDatum - 1; edStringAusgabe.Text:= Datetostr(dtDatum); end else begin edStringAusgabe.Text:= strString; end; end; end; end;
end. |
Eingabe Ausgabe
10-> 12
12,1-> 56,11
30.12.2009-> 29.12.2009
Bei allen andern Eingaben wird der eingegeben String wieder zurückgegeben.
Bis bald Chemiker
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!