Dezimalpunkt

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6914
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Dezimalpunkt

Beitrag von Mathias »

Da bin ich über eine rissen Falle gestolpert.

Je nachdem wie dir Ländereinstellungen in der Systemsteuerung stehen, funktioniert diese Zeile ohne Laufzeitfehler.

Code: Alles auswählen

// Deutsch (Schweiz)
Edit1.Text := FloatToStr(StrToFloat('123.456'));
 
// Deutsch (Deutschland)
Edit1.Text := FloatToStr(StrToFloat('123,456')); 


Ich hatte ein ein Tool für Flac.exe geschrieben, dies hatte ohne Probleme funktioniert, bis ich Windows neu installiert hatte, in dem ich versehentlich die Ländereinstellung nicht von DE auf CH geändert hatte.
Flac.exe verlangte bei DE für die Sekundentrennung ein ',' und mein Tool hatte einen '.' geschrieben.
Da kann man sehr lange üben, bis man den Fehler findet. :(

Ich finde dies echt Mühsam, da programmiert man als Schweizer ein Tool, und bei anderen Usern kommt ein Laufzeitfehler und man weis nicht warum.

Wie kann man dies am besten umgehen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Dezimalpunkt

Beitrag von Christian »

Die aktuelle Systemeinstelliung steht in Globaler Variable
DecimalSeparator
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

wp_xyz
Beiträge: 5142
Registriert: Fr 8. Apr 2011, 09:01

Re: Dezimalpunkt

Beitrag von wp_xyz »

Bei der Verwendung von "DecimalSeparator" meckert der Compiler, das wäre "deprecated", also überholt. Wenn dich das stört, solltest du stattdessen "DefaultFormatSettings.DecimalSeparator" verwenden.

Das hat allerdings den Nachteil, dass die gesamte Benutzeroberfläche nun das neu vereinbarte Dezimaltrennzeichen verwendet. Das kann Benutzer verwirren, wenn sie parout das Komma in das Edit-Feld eintippen wollen. Oft wird der Dezimalpunkt nur beim Dateizugriff benötigt, wenn Text-Dateien mit Dezimalpunkt eingelesen/geschrieben werden sollen. Aus diesen Grund gibt es alle wichtigen String-Konvertierungsfunktionen auch überladen mit den FormatSettings als zusätzlichem Parameter, so dass die Änderung nur in der entsprechende Routine wirkt. etwa so:

Code: Alles auswählen

 
var
  data: array of double;
 
procedure ReadFileToDataArray(AFileName: String);
var
  fs: TFormatSettings;   // in SysUtils
  L: TStringList;
  i: integer;
begin
  fs := DefaultFormatSettings;
  fs.DecimalSeparator := '.';
  L := TStringList.Create;
  try
    L.LoadFromFile(AFileName);
    SetLength(data, L.Count);
    for i:=0 to L.Count-1 do
      data[i] := StrToFloat(L[i], fs);  // statt "StrToFloat(L[i])"
  finally
    L.Free;
  end;
end;
 

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

Re: Dezimalpunkt

Beitrag von Michl »

Falls Du noch Tausender-Trennzeichen drinn hast, funktionieren DE/EN folgende Funktionen (ähnlich wp):

Code: Alles auswählen

function DeStrToFloat(const Str: String): Extended;
var
  fs: TFormatSettings;
begin
  fs:=DefaultFormatSettings;
  fs.DecimalSeparator:=',';
  Result:=StrToFloat(StringReplace(Str, '.', '', [rfReplaceAll]), fs);
end;
 
function EnStrToFloat(const Str: String): Extended;
var
  fs: TFormatSettings;
begin
  fs:=DefaultFormatSettings;
  fs.DecimalSeparator:='.';
  Result:=StrToFloat(StringReplace(Str, ',', '', [rfReplaceAll]), fs);
end;

Code: Alles auswählen

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

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

Re: Dezimalpunkt

Beitrag von Mathias »

Ich habe dies unterdessen genauer untersucht. Die Proceduren val und str arbeiten immer mit Dezimalpunkt, egal wie die Ländereinstellung ist.
Ich könnte diese beiden Proceduren verwenden, wem zwingen ein '.' verlangt wird, z.B. eine Quell-Codeerzeugung, da wird immer ein '.' verlangt.

Wie lange gibt es das Problem schon mit dem ',' als Trennung für Fliesskommazahlen. Früher als ich noch mit Turbo-Pascal und DOS programmiert hatte, war ich nie mit diesem Problem konfrontiert worden.
Ich kenne auch keine Programmiersprache oder auch CNC-Maschinen welche ein ',' für Fliesskommazahlen verwendet.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Dezimalpunkt

Beitrag von Michl »

Wenn Du jemanden eine Formatierung vorgeben willst, hilft Dir möglicherweise ein TMaskEdit. Damit kennst Du die Formatierung der Eingabe und kannst diese direkt verwenden.

Code: Alles auswählen

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

Antworten