[gelöst] Im Editfeld eingabe: 34.56 -> absturz

Für Fragen von Einsteigern und Programmieranfängern...
kromer
Beiträge: 3
Registriert: Do 14. Aug 2014, 13:00

[gelöst] Im Editfeld eingabe: 34.56 -> absturz

Beitrag von kromer »

Hallo,

bei der Eingabe einer Zahl mit einem Punkt als Dezimaltrennzeichen (z.B. 34.56) im Editfeld stürzt mein Programm ab.
Im Forum habe ich den DecimalSeperator gefunden und mit der Codezeile:

Code: Alles auswählen

 DecimalSeparator := '.';
kann man jetzt zwar 34.56 eingeben, dafür stürzt das Programm bei 34,56 ab.

Gibt es eine Möglichkeit, dass das Programm bei keiner Variante abstürzt, also weder bei einer Kommazahl noch bei einer durch Punkt getrennten Zahl?
Wichtig: Ich will nur den Absturz verhindern, es soll bei 34.56 eine Fehlermeldung zeigen und bei 34,56 einfach normal rechnen. Es muss also nicht beide Varianten rechnen können.
Zuletzt geändert von kromer am Di 26. Aug 2014, 12:18, insgesamt 1-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Michl »

Ich würde da mit einem try-except-Block den Fehler abfangen und eine Ausgabe mit der Exception machen. Siehe: http://wiki.freepascal.org/Logging_exce ... exceptions

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Antrepolit »

kromer hat geschrieben:(...)Gibt es eine Möglichkeit, dass das Programm bei keiner Variante abstürzt, also weder bei einer Kommazahl noch bei einer durch Punkt getrennten Zahl?
Wichtig: Ich will nur den Absturz verhindern, es soll bei 34.56 eine Fehlermeldung zeigen und bei 34,56 einfach normal rechnen. Es muss also nicht beide Varianten rechnen können.
Warum so kompliziert? Nimm einen

Code: Alles auswählen

TFloatSpinEdit
, denn eine Fehlermeldung ist unnötig und erfordert zusätzliche Klicks durch den Nutzer. So etwas sollte man vermeiden. Ebenso sollte man den DecimalSeparator nicht ändern. Deutsche Benutzer sind nunmal Kommazahlen gewohnt und englische Punktzahlen. Lazarus beachtet dies Lokalpezifisch. Ein Überschreiben dessen wird immer Benutzer unnötig verwirren und stellt das klassische Verlagren von Entwicklungsproblemen auf den Endbenutzer dar. So etwas macht man nicht.
Zuletzt geändert von Antrepolit am Do 14. Aug 2014, 23:17, insgesamt 1-mal geändert.
Grüße, Antrepolit

care only if your os is really burning

kromer
Beiträge: 3
Registriert: Do 14. Aug 2014, 13:00

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von kromer »

Ich hab's mit dem try-except gemacht und es geht, vielen Dank. Andrepolit, bei deiner Lösung weiß ich nicht wie man das umsetzt, du hast schon Recht, bei mir bekommt der Benutzer bereits mehrere Fehlermeldungen und das ist so langsam nicht mehr schön, aber für's erste reicht es so. Gruß

Linkat
Lazarusforum e. V.
Beiträge: 559
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22; Lazarus 3.4 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Linkat »

ich habe mir folgende kleine KommaInPunkt-Funktion geschrieben, die in meiner "MainUnit" zu finden ist, geschrieben.
Vor der Wandlung String in Float wird erst die Funktion durchlaufen.

Code: Alles auswählen

 
function KommaInPunkt(var s:string):string;
var i,l     :integer;
begin
  l:=Length(s);
  if l>0 then for i:=0 to l do if s[i]=',' then s[i]:='.';
  Result:=s;
end;
 
 

Code: Alles auswählen

 
var s  :String;
      r  :Double;
begin
  s:=Edit1.Caption;
  s:=KommaInPunkt(s);
  r:=StrToFloat(s);
end; 
 
nun kann man nach belieben ,,,,,,,, oder ...... eingeben (natürlich nur einmal!)

Gruß, Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Antrepolit »

Linkat hat geschrieben:ich habe mir folgende kleine KommaInPunkt-Funktion geschrieben, die in meiner "MainUnit" zu finden ist, geschrieben.
Vor der Wandlung String in Float wird erst die Funktion durchlaufen.

Code: Alles auswählen

 
function KommaInPunkt(var s:string):string;
var i,l     :integer;
begin
  l:=Length(s);
  if l>0 then for i:=0 to l do if s[i]=',' then s[i]:='.';
  Result:=s;
end;
 
 
(...)
Und damit wäre das Rad einmal mehr neu erfunden. Es gibt Stringreplace.
Grüße, Antrepolit

care only if your os is really burning

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Mathias »

Wen es auf Geschwindigkeit ankommt, ist die Lösung von Linkat effizienter.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Antrepolit »

Mathias hat geschrieben:Wen es auf Geschwindigkeit ankommt, ist die Lösung von Linkat effizienter.
Nein, ist sie nicht. StringReplace arbeitet mit Pointern. Abgesehen davon: es kommt hier nicht auf Geschwindigkeit an. Selbst wenn das TEdit-Feld voll geschrieben würde (sofern das geht), wann glaubst du, dass der Endbenutzer einen Unterschied merkt, ob das nun 10 oder 11 µS dauert? Man sollte Standardfunktionen verwenden um fehlerfreieren Code zu schreiben.
Zuletzt geändert von Antrepolit am Do 14. Aug 2014, 23:16, insgesamt 1-mal geändert.
Grüße, Antrepolit

care only if your os is really burning

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Mathias »

Antrepolit hat geschrieben:
Mathias hat geschrieben:Wen es auf Geschwindigkeit ankommt, ist die Lösung von Linkat effizienter.
Nein, ist sie nicht.
Wieso nicht ?

Noch einfacher wäre die procedure val, die nimmt immer ein Dezimalpunkt an ('.') .
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von m.fuchs »

Mathias hat geschrieben:
Antrepolit hat geschrieben:
Mathias hat geschrieben:Wen es auf Geschwindigkeit ankommt, ist die Lösung von Linkat effizienter.
Nein, ist sie nicht.
Wieso nicht ?
Wieso bist du der Meinung, dass sie effizienter sei? Warum das nicht so ist, hat Antrepolit ja dargelegt. Schreib doch einfach mal einen Testprogramm zum Vergleichen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von mse »

Linkat hat geschrieben:

Code: Alles auswählen

 
  if l>0 then for i:=0 to l do if s[i]=',' then s[i]:='.';
 
Achtung, Pascal string Index beginnt bei eins.

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Mathias »

Schreib doch einfach mal einen Testprogramm zum Vergleichen.
Habe ich gemacht, der Unterschied ist über das vierfache.

Code: Alles auswählen

const
  max = 1000000;
 
var
  s:array[0..max]of string;
 
{ TForm1 }
 
 
function KommaInPunkt(var s:string):string;
var i,l     :integer;
begin
  l:=Length(s);
  if l>0 then for i:=1 to l do if s[i]=',' then s[i]:='.';
  Result:=s;
end;
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  start,ende:cardinal;
begin
  for i := 0 to max do begin
    s[i] := FloatToStr(Random * 1000000);
  end;
 
  start := GetTickCount;
  for i := 0 to max do begin
    s[i]:= Stringreplace(s[i],'.',',',[]);
  end;
  ende := GetTickCount;
  Writeln('Zeit StringReplace:', Ende-Start);
 
 
  start := GetTickCount;
  for i := 0 to max do begin
    s[i]:= KommaInPunkt(s[i]);
  end;
  ende := GetTickCount;
  Writeln('Zeit Komma in Punkt:', Ende-Start);
end;
Abgesehen davon: es kommt hier nicht auf Geschwindigkeit an. Selbst wenn das TEdit-Feld voll geschrieben würde (sofern das geht), wann glaubst du, dass der Endbenutzer einen Unterschied merkt, ob das nun 10 oder 11 µS dauert? Man sollte Standardfunktionen verwenden um fehlerfreieren Code zu schreiben.
Da stimme ich dir zu, das spielt es keine Rolle.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von m.fuchs »

Ja, weil du das StringReplace auf JEDES Zeichen durchführst. Das ist ja auch totaler Quark.

So muss das gehen:

Code: Alles auswählen

s := StringReplace(s, '.', ',', [rfReplaceAll]);
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von Mathias »

Ich habe jetzt [rfReplaceAll] eingefügt, jetzt ist es noch langsamer geworden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Im Editfeld eingabe: 34.56 -> absturz

Beitrag von m.fuchs »

Du sollst aber nicht nur rfReplaceAll einfügen. Lies doch bitte noch einmal meinen Beitrag komplett. So lang ist der nicht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten