Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   inifile ReadFloat deutsch/english formatsettings (https://www.delphipraxis.net/208319-inifile-readfloat-deutsch-english-formatsettings.html)

bernhard_LA 14. Jul 2021 12:03

inifile ReadFloat deutsch/english formatsettings
 
Würde gerne mit einem Deutschen Windows PC ( dezimale = 1,2 ) Ini files einlesen die jemand auf einem englischen PC geschrieben hat ( 1.2)
mit der Funktion Ini.ReadFloat(....) .
Was muss ich machen damit ich beide Formate einlesen kann ?


Delphi-Quellcode:
fIni := TIniFile.Create(aFileName);
  try

    X := fIni.ReadFloat(SectionStr, 'x', -99999); //  mag nur Komma-Zahlen mit Deutschen Format 1,2   :-( 


  finally
    fIni.free;
  end;

bcvs 14. Jul 2021 12:11

AW: inifile ReadFloat deutsch/english formatsettings
 
Als String einlesen und mit StrToFloat umwandeln. Dabei die FormatSettings nach Bedarf setzen.

bernhard_LA 14. Jul 2021 12:24

AW: inifile ReadFloat deutsch/english formatsettings
 
gibt's ne Lösung bei der ich nix selber schreiben muss .... eigentlich doch ne Aufgabe der Klasse inifile ......

himitsu 14. Jul 2021 12:37

AW: inifile ReadFloat deutsch/english formatsettings
 
Erstmal ist es totaler Schwachsinn, dass INIs überhaupt lokalisiert gespeichert/gelesen werden.
(aber für INIs gibt es ja leider auch eigentlich keine globale einheitliche Konvention/Richtline/Norm/...)
Und leider kam in den letzten 20 Jahren auch noch keiner auf die Idee eine FormatSettings-Variable in TCustomIniFile für Floats und DateTimes einzufügen.

Fazit:
  • Du mußt, wie schon gesagt wurde, selbst den Float behandeln
    Delphi-Quellcode:
    StrToFloat(INI.ReadString(...), DeinFormatSettings)
    • manuell, vor Ort
    • TIniFile ableiten und diese Funktionen überschreiben überdecken
    • oder besser noch einfach mit einem ClassHelper erweitern, z.B. um ein ReadFloatUS
  • oder du stellst das globale FormatSettings in der SysUtils um
    • also entweder vor und nach dem Zugriff auf die INI, vorübergehend (aber ist auch keine gute Idee, da nicht threadsave usw.)
    • oder permanent dein Programm auf Englisch umstellen
      Delphi-Quellcode:
      System.SysUtils.FormatSettings := TFormatSettings.Create('en-US');

Aber vielleicht wird das Problem ja im nächsten Jahrtausend behoben sein. :stupid:
https://quality.embarcadero.com/browse/RSP-17616

Der schöne Günther 14. Jul 2021 12:49

AW: inifile ReadFloat deutsch/english formatsettings
 
Oder du machst es dir einmal als
Delphi-Quellcode:
class helper
und benutzt dann einfach die folgende Unit in deiner
Delphi-Quellcode:
uses
. Das ist das schwere Los eines Software-Entwicklers, manchmal muss man doch tatsächlich wenigstens noch ein
Delphi-Quellcode:
uses
tippen.


Delphi-Quellcode:
unit System.IniFiles.TCustomIniFile.Helper;

interface uses System.IniFiles, System.SysUtils;

type
   /// <summary>
   ///     Ersetzt die Methode
   ///    <c>WriteFloat</c> und deren <i>Read</i>-Gegenstück da die
   ///    RTL-Implementation von <c>TCustomIniFile</c> dummerweise
   ///    mit den <b>globalen Formatsettings</b> arbeitet
   /// </summary>
   /// <remarks>
   ///     Floats werden mit <c>.</c> als <c>DecimalSeparator</c> geschrieben.
   /// </remarks>
   TCustomIniFileHelper = class helper for TCustomIniFile
      protected class var
         internalFormatSettings: TFormatSettings;
      protected
         class constructor Create();
      public
         procedure WriteFloat(const Section, Name: string; Value: Double);
         function ReadFloat(const Section, Name: string; Default: Double): Double;
   end;


implementation

{ TCustomIniFileHelper }

class constructor TCustomIniFileHelper.Create();
begin
   internalFormatSettings := TFormatSettings.Invariant();
end;

function TCustomIniFileHelper.ReadFloat(
   const Section, Name: string;
   Default: Double
): Double;
var
   FloatStr: string;
begin
   FloatStr := ReadString(Section, Name, '');
   Result := Default;
   if FloatStr <> '' then
   try
      Result := StrToFloat(FloatStr, internalFormatSettings);
   except
      on EConvertError do
         Result := inherited ReadFloat(Section, Name, Default);
   else
      raise;
   end;
end;

procedure TCustomIniFileHelper.WriteFloat(
   const Section, Name: string;
   Value: Double
);
begin
   WriteString(Section, Name, FloatToStr(Value, internalFormatSettings));
end;

end.

Uwe Raabe 14. Jul 2021 14:24

AW: inifile ReadFloat deutsch/english formatsettings
 
Zitat:

Zitat von bernhard_LA (Beitrag 1492271)
gibt's ne Lösung bei der ich nix selber schreiben muss .... eigentlich doch ne Aufgabe der Klasse inifile ......

Das sehen andere zwar auch so (https://quality.embarcadero.com/browse/RSP-17616), aber solange das nicht implementiert ist musst du wohl selber ran.

Rolf Frei 14. Jul 2021 16:30

AW: inifile ReadFloat deutsch/english formatsettings
 
Doppelpost

Rolf Frei 14. Jul 2021 16:53

AW: inifile ReadFloat deutsch/english formatsettings
 
Eigentlich reicht es doch einfach das DecimalChar zu setzen:
Delphi-Quellcode:
var OrgDecSep: Char;
fIni := TIniFile.Create(aFileName);
  try
    try
      X := fIni.ReadFloat(SectionStr, 'x', -99999); // mag nur Komma-Zahlen mit Deutschen Format 1,2 :-(
    except
      OrgDecSep := FormatSettings.DecimalSeparator;
      try    
        FormatSettings.DecimalSeparator := '.';
        X := fIni.ReadFloat(SectionStr, 'x', -99999); // mag nur Komma-Zahlen mit Deutschen Format 1,2 :-(
      finally
        FormatSettings.DecimalSeparator := OrgDecSep;
      end;
    end;
  finally
    fIni.free;
  end;

Oder wenn du genau weisst, dass das INI nach US/ANSI Regel gespeichert wurde, kannst du das auch einmalig vor der Verarbeitung der INI machen:
Delphi-Quellcode:
var OrgDecSep: Char;
OrgDecSep := FormatSettings.DecimalSeparator;
fIni := TIniFile.Create(aFileName);
  try
    FormatSettings.DecimalSeparator := '.';
    X := fIni.ReadFloat(SectionStr, 'x', -99999); // mag nur Komma-Zahlen mit Deutschen Format 1,2 :-(
    ... weitere ReadFLoat, etc.
  finally
    FormatSettings.DecimalSeparator := OrgDecSep;
    fIni.free;
  end;

Uwe Raabe 14. Jul 2021 16:54

AW: inifile ReadFloat deutsch/english formatsettings
 
Zitat:

Zitat von Rolf Frei (Beitrag 1492287)
Eigentlich reicht es doch einfach den DecimalSeparator zu setzen

Wenn sich das ganze nicht in einem Thread abspielt, geht das wohl.

himitsu 14. Jul 2021 17:29

AW: inifile ReadFloat deutsch/english formatsettings
 
Es ist egal, ob DAS in einem Thread oder im Hauptthread abläuft ... wenn irgendwer Anderes in einem "anderen" Thread gleichzeitig das auch nutzen oder gar ebenfalls ändern will, dann ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:55 Uhr.
Seite 1 von 3  1 23   

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf