Decimalseparator Problem

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Decimalseparator Problem

Beitrag von DL3AD »

Hallo,

hier mal ein Programmschnipsel

Code: Alles auswählen

 
var
  Form1: TForm1;
  DefaultFormatSettings: TFormatSettings;
 
implementation
{$R *.lfm}
{ TForm1 }
//Initialisierungen
procedure TForm1.FormCreate(Sender: TObject);
begin
//  DecimalSeparator:='.';
  DefaultFormatSettings.DecimalSeparator:= '.';
end;
 
//Test
procedure TForm1.Button1Click(Sender: TObject);
var
  L_wert: UnicodeString;
  Lwert: Extended;
begin
  L_wert:= '1.0';//Eingangswerte mit einer Kommastelle
  Lwert:= StrTofloat(L_wert);//Umwandel in Float zur Berechnung
end;       
 


Ich habe nun versucht den veralteten DecimalSeparator:='.' durch das aktuelle DefaultFormatSettings.DecimalSeparator:= '.' zu ersetzen.
Mit dem alten DecimalSeparator:='.' funktioniert meine Anwendung sowohl unter Windows und auch Linux.
Mit dem neuen DefaultFormatSettings.DecimalSeparator:= '.' gibt es einen Fehler EConvertError unter Windows - Linux funktioniert.

Was mache ich da falsch ?

Gruß Frank

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Decimalseparator Problem

Beitrag von theo »

Du brauchst das nicht in deinem Code deklarieren, das ist schon eine globale Variable.

Streiche

Code: Alles auswählen

var
..
  DefaultFormatSettings: TFormatSettings;

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

Re: Decimalseparator Problem

Beitrag von Mathias »

Versuche es mal so:

Code: Alles auswählen

  Lwert:= StrTofloat(L_wert, DefaultFormatSettings); //Umwandel in Float zur Berechnung


Wobei ich einen anderen Namen als DefaultFormatSettings nehmen würde, da dies in der LCL schon vorhanden ist. :wink:

Dann funktioniert sogar so was. :mrgreen:

Code: Alles auswählen

var
  myFormatSettings: TFormatSettings;
begin
  myFormatSettings.DecimalSeparator := 'x';
  Lwert := StrToFloat('123x456', myFormatSettings);
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Decimalseparator Problem

Beitrag von DL3AD »

...hmm so muss ich ja bei jeder Umformatierung Änderungen vornehmen. :shock:
Mit dem alten DecimalSeparator:='.' funktionierte es dann global für das gesammte Projekt.
Gibt en nach der neuen Methode auch eine globale Einstellung ?

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

Re: Decimalseparator Problem

Beitrag von Mathias »

So wie es theo macht, sollte es global gehen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Decimalseparator Problem

Beitrag von DL3AD »

...hmm, ich möchte dass der '.' sowohl unter Windows und Linux als Dezimalseperator gilt - und zwar unabhänig von den Betriebssystemeinstellungen ist.
Also muss ich etwas angeben.
Was genau muss ich denn nun angeben ?

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

Re: Decimalseparator Problem

Beitrag von Mathias »

Wen du ein Punkt willst, dann nimm doch die Funktionen Str und Val, diese Funktionen sind unabhängig vom OS/Lazarus. So nebenbei sind diese sehr schnell.
StrToFloat und FloatToStr verwenden schlussendlich auch diese beiden Funktionen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Decimalseparator Problem

Beitrag von DL3AD »

OK - kannst du mal ein Beispiel geben damit ich verstehe was genau du meinst.

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

Re: Decimalseparator Problem

Beitrag von Mathias »

So nebenbei kann du noch sehr einfach Formatieren.
Und eine Fehlerauswertung ist auch noch dabei. :wink:

Code: Alles auswählen

var
  f: single;
  s: string;
  e: integer;
 
begin
  f := 123.456;
  Str(f, s);
  WriteLn(s);
  Str(f: 10: 4, s);
  WriteLn(s);
 
  s := '654.321';
  Val(s, f, e);
  if e <> 0 then begin
    WriteLn('Fehler');
  end else begin
    WriteLn(f);
    WriteLn(f: 10: 4);
  end;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Decimalseparator Problem

Beitrag von DL3AD »

DANKE!
nun ist alles klar 8) - baue meinen Code um.

Selten so ein gutes Forum mit so hilfreichen Usern gefunden wie dieses.

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

Re: Decimalseparator Problem

Beitrag von wp_xyz »

Hast du theo's Vorschlag nicht verstanden? Das ist doch viel einfacher!

Hier nochmal dein Code aus dem 1.Beitag (deine eigenen Kommentare habe ich entfernt). Entferne einfach deine eigene Deklaration von DefaultFormatSettings, dann funktioniert alles ohne weitere Änderung. Denn DefaultFormatSettings in der Original-Deklaration in SysUtils wird für die String-Zahl-Konvertierung verwendet. Durch deine eigene Deklaration unter demselben Namen wird die richtige nicht mehr verwendet.

Code: Alles auswählen

var
  Form1: TForm1;
 // DefaultFormatSettings: TFormatSettings;  <--- das muss weg, denn des ist bereits in SysUtils deklariert
 
implementation
{$R *.lfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
  DefaultFormatSettings.DecimalSeparator:= '.';   // <--- Nun bezieht sich das auf die DefaultSettings in SysUtils, die in den Konvertierungsfunktionen verwendet werden
end;
 
//Test
procedure TForm1.Button1Click(Sender: TObject);
var
  L_wert: UnicodeString;               // <--- und warum hier UnicodeString und nicht String?
  Lwert: Extended;
begin
  L_wert:= '1.0';
  Lwert:= StrTofloat(L_wert);
end;

Aber mein üblicher Vorbehalt in diesem Zusammenhang: Es ist bei uns nun mal üblich, Dezimalzahlen mit Komma zu schreiben, nicht mit Punkt. Eigens dafür gibt es die entsprechenden Betriebssystemeinstellungen. Wenn du das umgehst, wird dein Programm für jeden Nicht-Programmierer unnötig schwer benutzbar. Denn er erhält bei jeder Eingabe des für ihn gewohnten Kommas eine Fehlermedlung. Solche Software überlebt auf meinem Rechnen nur den 1. Start. Wenn du unbedingt Zahlen mit Punkt eingeben willst, dann ändere es im Betriebssystem deines Rechners, dann verhalten sich auch alle anderen Programme so. Und wenn deine Kunden lieber das Komma wollen, dann funktioniert alles wie gewohnt.
Zuletzt geändert von wp_xyz am Mo 6. Nov 2017, 11:03, insgesamt 1-mal geändert.

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

Re: Decimalseparator Problem

Beitrag von Mathias »

Es ist bei uns nun mal üblich, Dezimalzahlen mit Komma zu schreiben, nicht mit Punkt.

Das betrifft fast nur den Office-Bereich.
Aber nur im EU Raum, in der CH und USA wird ein Punkt verwendet, welches auch in der Muttersprache des PCs ist. Ansonsten würde Val und Str keinen Punkt verlangen.

Oder wen man zB. OBJ-Wavefront Dateien bearbeiten will, ist man auf den Punkt angewiesen.
Oder fast alle Programmiersprachen verwenden einen Punkt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Decimalseparator Problem

Beitrag von DL3AD »

Hallo wp_xyz,

nun ist es mir klar geworden - Mein Denkfehler war dass ich DefaultFormatSettings: TFormatSettings definiren muss - aber es ist ja schon eine globale Variable - dass wuste ich nicht.
Danke für deine wie immer gute verdeutlichung des Sachverhaltes.

Gruß
Frank

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Decimalseparator Problem

Beitrag von theo »

@Mathias; Lass doch eine richtige Antwort einfach mal unkommentiert, bis sich der Fragende wieder meldet.
Wenn die Antwort nicht klar ist, kannst du dich immer noch einbringen.
So verwirrst du mehr als du hilfst.

Danke.

Antworten