INI-File: welches Format beim Lesen und Schreiben?

Rund um die LCL und andere Komponenten
Benutzeravatar
photor
Beiträge: 200
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux (L 2.0.10 FPC 3.2.0)
CPU-Target: 64Bit

INI-File: welches Format beim Lesen und Schreiben?

Beitrag von photor »

Hallo Forum,

ich nutze gerne INI-Files, um Parameter-Sätze für verschieden Programme zu speichern. Die Programme laufen teils auf Linux (Lazarus) und Windows10 (Delphi), teil im internationalen Umfeld (Arbeitsgruppe).

Jetzt bin ich beim Lesen aus einem INI-File auf ein Problem gestoßen: ein INI.ReadFloat liefert einen unplausiblen Wert (bzw. der wird nicht als Float erkannt). Mein Verdacht ist, dass das mit der Darstellung der Zahlen (Float, aber auch Datum) je nach Lokalisierung (',' bzw '.' mal als Dezimaltrenner, mal als Tausendertrenner - wer braucht das eigentlich?) zu tun haben könnte. [*]

Nun habe ich gefunden, dass INI.ReadFloat auch nichts anderes macht, als ein INI.ReadString mit anschließendem StrToFloat; letzterem kann ich ja ein Format mitgeben, was als erster Lösungsansatz dienen könnte.

Trotzdem frage ich mich, ob man das Problem nicht grundsätzlich angehen kann - zumindest Programm-intern einmal das Format (international ist im Ingenieurumfeld bestimmt kleinster Nenner) einstellen und dann werden alle Ein- und Ausgaben in der Lokalisierung gemacht - unabhängig davon, was auf dem Rechner sonst eingestellt ist[**]. Gibt es da einen guten Ansatz?

Dankbar für jede Anregung.
Photor


[*] das Problem besteht natürlich auch schon beim Schreiben des INI; für den Test habe ich das nur im Texteditor angepasst.
[**] nicht mal in der Arbeitsgruppe sind die Rechner konsistent aufgesetzt.

sstvmaster
Beiträge: 342
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: OS: Windows 10 | Lazarus: 2.0.8 + Fixes + Trunk 32bit
CPU-Target: 32Bit
Wohnort: Dresden

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von sstvmaster »

Ich habe in vielen ini Dateien, wo die Exe International verwendet wird, das Datum als Unix Zeit gesehen.

Das mit den Floats als Komma und Punkt ist leider eine bescheidene Sache, ich setze in meinen Programmen dann

Code: Alles auswählen

uses SysUtils;
...
DefaultFormatSettings.DecimalSeparator := '.';
und versuche im ganzen Programm damit zu arbeiten. Eingabefelder mit Komma
prüfe ich und wandle ggf. Komma in Punkt.
LG Maik

Winni
Beiträge: 273
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Winni »

Hi!

Datums-Separator, Dezimal-Separator etc kannst Du doch einstellen über:

Code: Alles auswählen

DefaultFormatSettings: TFormatSettings = (CurrencyFormat: 1; NegCurrFormat: 5; ThousandSeparator: ','; DecimalSeparator: '.'; CurrencyDecimals: 2; DateSeparator: '-'; TimeSeparator: ':'; ListSeparator: ','; CurrencyString: '$'; ShortDateFormat: 'd/m/y'; LongDateFormat: 'dd" "mmmm" "yyyy'; TimeAMString: 'AM'; TimePMString: 'PM'; ShortTimeFormat: 'hh:nn'; LongTimeFormat: 'hh:nn:ss'; ShortMonthNames: ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); LongMonthNames: ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); ShortDayNames: ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); LongDayNames: ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); TwoDigitYearCenturyWindow: 50);

Denk Dir doch einen Standard für Dein Programm aus. Dann setzt Du den entsprechenden Separator bzw. das Format und liest/screibst Deinen Ini-File. Dann setzt Du die Werte wieder zurück, damit im restlichn Programm nix schief geht.

Winni

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Mathias »

Ich wandle Floats und Strings immer mit val und str um. Da kann man sich verlassen, das immer der . als Trenner verwendet wird. Der PC verwendet intern immer einen Punkt. Mit dem Komma als Trenner hat man nur Ärger.

Wen dem Komma habe ich mal einen ganzen Tag verloren.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von wp_xyz »

Ohne die FormatSettings der Anwendung zu verstellen, kann man auch für die IniFile eigene FormatSettings definieren. Dort würde ich den Dezimalpunkt als DecimalSeparator nehmen, und für das Datumsformat sowas wie 'yyyy/mm/dd' mit DateSeparator '-' oder '/'. Das muss man natürlich für die Schreib- und Lese-Routine machen. Daher bietet sich an, das in eine eigene Routine auszulagern:

Code: Alles auswählen

function CreateIni(const AFileName: String): TCustomIniFile;
begin
  Result := TIniFile.Create(AFileName);
  Result.FormatSettings.DecimalSeparator := '.';
  Result.FormatSettings.DateSeparator := '/';
  Result.FormatSettings.ShortDateFormat = 'yyyy/mm/dd';
end;

Benutzeravatar
photor
Beiträge: 200
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux (L 2.0.10 FPC 3.2.0)
CPU-Target: 64Bit

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von photor »

Hallo,

erstmal vielen Dank an alle für den Input. Tenor ist aber, du must dich selbst kümmern (eigentlich traurig). Genau sowas hatte ich ja befürchtet.

Aber besser man fragt vorher nochmal:
wp_xyz hat geschrieben:
Fr 29. Mai 2020, 17:39
Ohne die FormatSettings der Anwendung zu verstellen, kann man auch für die IniFile eigene FormatSettings definieren. Dort würde ich den Dezimalpunkt als DecimalSeparator nehmen, und für das Datumsformat sowas wie 'yyyy/mm/dd' mit DateSeparator '-' oder '/'. Das muss man natürlich für die Schreib- und Lese-Routine machen. Daher bietet sich an, das in eine eigene Routine auszulagern:

Code: Alles auswählen

function CreateIni(const AFileName: String): TCustomIniFile;
begin
  Result := TIniFile.Create(AFileName);
  Result.FormatSettings.DecimalSeparator := '.';
  Result.FormatSettings.DateSeparator := '/';
  Result.FormatSettings.ShortDateFormat = 'yyyy/mm/dd';
end;


Das kannte ich noch nicht (weil ich wohl noch nicht bis TCustomIniFile vorgedrungen war. Aber das ist eine spannende Möglichkeit: der Code passt einfach in die normalen Routinen zum Lesen und Schreiben und ich habe das Format immer festgelegt (die INIFiles funktionieren sowieso nur für das jeweilige Programm, das teste ich ab; also Austausch zwischen verschiedenen Programmen findet nicht statt).

Das werde ich probieren ... und berichten.

Danke,
Photor

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Mathias »

Das es Leute gibt, die im Office Bereich auf ein Komma als Dezimaltrenner setzen, begreife ich, aber System relevante Sachen, so wie es in eine INI oder XML der Fall ist, sollte immer ein Punkt verwendet werden.
Ansonsten hat man Probleme, wen man solche Dateien in verschiedenen Ländern verwenden will.

Nach meiner Meinung sollte das ini.ReadFloat selbst machen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
photor
Beiträge: 200
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux (L 2.0.10 FPC 3.2.0)
CPU-Target: 64Bit

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von photor »

Ja. So denke ich auch: allenfalls könnte man die Darstellung(!) der Zahlen bei der Ausgabe dem jeweiligen Umfeld anpassen. Aber die Speicherung und das Handling sollte doch irgendwie genormt sein (oder sich zumindest so einstellen lassen - einfach und konsistent!).

Komma als Dezimal- und Punkte als Tausendertrenner mag ich im Finanzwesen noch verstehen. Der Ingenieurbereich (einschließlich Mathematik, Physik und Informatik) ist international und da würde ich die anglo-amerikanische Schreibweise als de-facto-Standard ansehen.

Wenn ich jetzt noch sehe, was passiert, wenn man ein deutsche Office installiert hat und mit "wenn" und so programmieren muss ... (sorry, ich muss mal gerade um die Ecke).

Aber das führt jetzt vom Thema weg.

Ciao,
Photor

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Mathias »

Was noch interessant ist, ich code schon über 30Jahre. Für mich war es immer selbstverständlich ein Punkt als Trenner zu verwenden. Das in Deutschland ein Komma dafür verwendet wird, habe ich erst vor ein Paar Jahren erfahren, als ein Programm zicken machte das war dieses, mit dem ich einen Tag verloren hatte.
Ich hatte mal versehentlich die Länderereinstellungen auf DE anstelle CH.
Daher verwende ich immer val und str.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 599
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.7 FPC 3.04)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von fliegermichl »

Man könnte sich ja eine TStdFormatINIFile Klasse ableiten und da diese Formatsettings durchführen.
Wenn man dann die anstelle von TINIFile verwendet, braucht man sich nachher nie mehr drum kümmern.

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Mathias »

Gibt es nicht mit XML so was ähnliches ?
Da hat es Units mit ein 2 dahinter. Die sollten utf8 oder was ähnliches tauglich sein.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
photor
Beiträge: 200
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux (L 2.0.10 FPC 3.2.0)
CPU-Target: 64Bit

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von photor »

Hm. Mit XML oder ähnlichem wollte ich gar nicht anfangen. Die Config-Files sollten einfach und mit einem Editor von Nicht-informatischem Fach-Ingenieur bearbeitbar sein: da muss vielleicht eine Variante mit einem oder zwei geänderten Parametern durch gerechnet werden. Das geht am einfachsten, wenn man einen ASCII-Editor anwirft, den Wert ändert und die Rechnung anwirft. In einem INI-File findet jeder die passende Zeile. XML kann (in meinen Vorurteils-behafteten Augen) deutlich unübersichtlicher sein.

Man kann auch so ausdrücken: was komplizierteres als das will ich den Kollegen nicht zumuten :wink:

Ciao,
Photor

Timm Thaler
Beiträge: 1049
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Timm Thaler »

Im Gegenteil, XML ist das neue Config unter Linux und funktioniert wunderbar.

Auch Ini-Dateien können krachen, wenn Nutzer drin rumschreiben und falsche Keys verwenden. Das ist nix, wo User drin rumschreiben sollen. (Ok, ich machs auch.)

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

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Mathias »

Wieso nur Linux xml funktioniert doch auch unter Win wunderbar ?
Ach stimmt ja unter Win gibt es die vermüllbare Registry. 😁

Früher hatte ich auch ini verwendet, aber unterdessen verwende ich auch lieber xml.
Man ist sehr flexibel und trotzdem übersichtlich.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1049
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: INI-File: welches Format beim Lesen und Schreiben?

Beitrag von Timm Thaler »

Ja das ist richtig, ich verwende XML auch unter Win als Config-Files. Aber es ist halt nicht sehr verbreitet.

Und Lazarus bietet auch die direkte Einbindung von XML-Config ähnlich wie Ini-Config in die GUI. So werden z.B. Fensterpositionen automatisch beim Beenden abgespeichert und beim Starten geholt, ebenso gesetzte Checkboxen, Inhalte von Stringfeldern usw.

Antworten