Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Komma/Punkt Dezimalseperator (https://www.delphipraxis.net/79347-komma-punkt-dezimalseperator.html)

DoktorD 20. Okt 2006 16:24


Komma/Punkt Dezimalseperator
 
Hi. Habe ein Programm geschreiben, das beim Starten aus einer INI-Datei Werte einliest (z.B. 1,50) und dann mit "StrToFloat" umwandelt.
Das läuft soweit alles super aber nun habe ich as Programm bei einem Freund ausprobiert (anderer Rechner) und da kommen beim Starten Fehlermeldungen.

"... ist kein gültiger Gleitkommawert"

Also ich hab da sowas in meiner Erinnerung, dass man im Windows den Dezimalseperator umstellen kann.

Wie kann ich dieses Problem aber nun lösen? Kann diese Umstellung über eine Funktion realisieren?

Maja Jessica 20. Okt 2006 16:30

Re: Komma/Punkt Dezimalseperator
 
Hi

Hilft Dir dieses?:
Decimalseparator

MJ

DoktorD 20. Okt 2006 16:33

Re: Komma/Punkt Dezimalseperator
 
Das kenn ich schon, damit kann ich das ja nur einmal umstellen, und dann läuft es ja auf meinem Rechner nicht mehr, da ich ja dann den Wert den ich einlese in einen in 2.50 Umwandeln müsste.

Maja Jessica 20. Okt 2006 16:48

Re: Komma/Punkt Dezimalseperator
 
Hi,

also kein Problem, da du ihn ja auch auslesen
Delphi-Quellcode:
ShowMessage(decimalseparator);
und darauf reagieren kannst. (pos, replace)

MJ

Leonard 20. Okt 2006 16:56

Re: Komma/Punkt Dezimalseperator
 
Hallo,

Wenn ich mich recht erinnere, könntest auch die StrToFloat nehmen, in der du die FormatSettings mit angibst. So kannst du angeben, welcher DecimalSeparator verwendet wird. Dies sollte dann unabhängig von den Windoseinstellungen sein.

mfg Leonard

DoktorD 20. Okt 2006 16:57

Re: Komma/Punkt Dezimalseperator
 
Kann ich denn irgendwie die Einstellungen bei Regions- und Sprachoptionen nur für mein Programm ändern. Geht das überhaupt???

RavenIV 20. Okt 2006 16:58

Re: Komma/Punkt Dezimalseperator
 
ich mach das immer so:
- das StrToFloat in einen try..except reinsetzen
- bei except dann den DecimalSeperator umstellen (vorher den alten Wert merken)
- dann nochmal StrToFloat
- dann den DezimalSeperator wieder zurückstellen

OldGrumpy 20. Okt 2006 17:01

Re: Komma/Punkt Dezimalseperator
 
Eleganter ist es, sich die aktuellen Landeseinstellungen in ein Formattemplate zu holen und die dann für die neuere Variante von StrToFloat zu verwenden:

Delphi-Quellcode:
uses SysUtils;
...
var
  fs        :TFormatSettings;
  MeinString :String;
  MeineZahl :Double;
...
begin
...
  GetLocaleFormatSettings(GetUserDefaultLCID, fs);
  MeineZahl:=StrToFloat(MeinString, fs);
...
EDIT:
Nachtrag: Natürlich ist es so auch möglich, Zahlen die immer im gleichen Format vorliegen, unabhängig von den aktuellen Einstellungen des Rechners umzuwandeln. Dafür gibt man einfach bei GetLocaleFormatSettings seine eigene LCID an. Die kann man ja einfach per GetUserDefaultLCID ermitteln :)

EDIT:
Nachtrag 2: Ich hoffe, die Erklärung ist jetzt nicht allzu wirr. Für die Anwendung "wandle eine beliebige eingegebene Kommazahl so um wie der User es erwartet" gilt meine obige Version, für die Aufgabe "wandle Zahlen aus einem Datenfile unabhängig von der Ländereinstellung des Rechners" gilt die Empfehlung aus Nachtrag 1 :)

Leonard 20. Okt 2006 17:05

Re: Komma/Punkt Dezimalseperator
 
Hallo,

Zitat:

Zitat von OldGrumpy
Delphi-Quellcode:
...
  GetLocaleFormatSettings(GetUserDefaultLCID, fs);
  MeineZahl:=StrToFloat(MeinString, fs);
...

Dann aber noch
Delphi-Quellcode:
  fs.DecimalSeparator := ',';
zwischen die beiden Zeilen setzen, sonst nimmt er wieder nur die Windowseinstellungen.

OldGrumpy 20. Okt 2006 17:06

Re: Komma/Punkt Dezimalseperator
 
Leonard, lies bitte die beiden Nachträge in meinem Post :)

Und umstellen braucht man für diese Aufgabe ansonsten auch nix :) Man muss sich halt nur das Formattemplate holen was zu den zu wandelnden Daten passt:

User gibt Zahl ein wie gewohnt:
Delphi-Quellcode:
GetLocaleFormatSettings(GetUserDefaultLCID, fs); //berücksichtigt Komma- und Tausendertrennzeichen wie der User es auf seinem Rechner gewohnt ist
Programm benutzt ein Datenfile mit Kommazahlen im Format für ein bestimmtes Land:
Delphi-Quellcode:
GetLocaleFormatSettings(1033, fs); //holt zum Beispiel das Template für Deutschland
Nun klarer? :)

Leonard 20. Okt 2006 17:10

Re: Komma/Punkt Dezimalseperator
 
Zitat:

Zitat von OldGrumpy
Leonard, lies bitte die beiden Nachträge in meinem Post :)

ok, ok, jetzt sind die auch angekommen. Ich werde das nächste mal erst den :warn: machen, nachdem 2 Edits da sind. :-D

DoktorD 20. Okt 2006 17:20

Re: Komma/Punkt Dezimalseperator
 
Genau sowas wollte ich wissen. Super, vielen Dank!!!

Hansa 20. Okt 2006 17:22

Re: Komma/Punkt Dezimalseperator
 
Macht ihr das aber kompliziert. :stupid: Eine INI-Datei ist nur eine Textdatei und wenn da 1,50 drin steht, dann ist das eben so. Statt StrReplace und anderes einzusetzen hätte ich schon längst die 1,50 abgespeichert als 150. Dann braucht man nämlich nur durch 100 zu teilen und egal wie die Ländereinstellungen sind, es wird immer funktionieren.

Luckie 20. Okt 2006 17:32

Re: Komma/Punkt Dezimalseperator
 
Und wenn er da was mit den Ländereinstellungen reinschreibt? Würde ich übrigens auch so erwarten.

Hansa 20. Okt 2006 17:47

Re: Komma/Punkt Dezimalseperator
 
Du meinst, wenn er da z.B. "Äpfel" in die INI reinschreibt ? Das Ä könnte dann falsch angezeigt / gedruckt werden. Ein Ami würde aber wohl kaum irgendwo deutsche Umlaute drin haben wollen. :shock: Theoretisch vielleicht. Praktisch dürfte so ein Fall äußerst selten vorkommen. Wenn aber schon eine Zahl das Programm zum abstürzen bringen kann (StrToFloat geht nicht => falsche Initialisierung und und...), da hörts auf. 8) Das muß echt nicht sein.

Luckie 20. Okt 2006 20:04

Re: Komma/Punkt Dezimalseperator
 
Wenn du mich nicht verstehen willst, dan antworte bitte auch nicht. Du hast selsbt das beispiel mit der 1,5 angeführt. Würde das auf einem amerikanischen Rechner länderspezifisch gespeichert werden, wäre das 1.5. Bei dir würde aber nach wie vor 1,5 in der Ini-Datei stehen.

OldGrumpy 20. Okt 2006 20:39

Re: Komma/Punkt Dezimalseperator
 
Ausserdem mal wieder viel zu kurz gedacht, was ist wenn die Daten aus einer Quelle stammen, über die man keine Kontrolle hat? Zum Beispiel nen Aktienkursticker. Inwiefern eine Lösung, die einem mit ziemlich wenig "Mehraufwand" viel Kopfschmerzen erspart, als umständlich zu bezeichnen ist, ist fraglich :)
Ich versuche meine Projekte von Anfang an so auszulegen dass a) Übersetzung (Lokalisierung) kein grosses Problem ist, und b) der Code möglichst überall gleich funktioniert. Das erspart einem später viel Aufwand.

Hansa 20. Okt 2006 20:50

Re: Komma/Punkt Dezimalseperator
 
Zitat:

Zitat von Luckie
Wenn du mich nicht verstehen willst...

Äh, Luckie, Du verstehst lediglich mich nicht. :mrgreen: Es gibt Probleme mit ,. also Decimalseparator. Was liegt da näher, dieses vollständig zu eliminieren und die Zahl einfach als Ganzzahl in die INI zu schreiben. Sofern nicht im Programm noch sonstwo , oder . im Klartext drin steht und es wird auch die Funktion DecimalSeparator stattdessen verwendet, dann wird das Programm laufen. Im Falle von 1,5 speichere ich 150 in der INI, lese das auch daraus, teile durch 100 und fertig. Speichere ich stattdessen 1,50 in der INI und versuche das irgendwie als Zahl aus der Ini zu lesen : es wird krachen. Außer im deutschsprachigen Raum und da ist das nicht mal garantiert. Wenn es aber überall sonst sowieso falsch ist, dann fange ich doch nicht an, eine nicht astreine INI ins Ausland zu liefern und dann mühselig mit StringReplace oder sonstwie richtig zu biegen nur um eine einzige Division zu sparen. 8)

Luckie 20. Okt 2006 21:21

Re: Komma/Punkt Dezimalseperator
 
Oh Gott. Und wenn du vorher nicht weißt wie viele Kommastellen es sind? Speichern kann man es ja noch. Aber woher weißt du durch was für eine zehner Potenz du beim Auslesen Teilen musst? Willst du das auch noch mit abspeichern? Warum nicht die Methode von OldGrumpy nehmen? Die ist effizient, einfach und fehlerfrei richtig angewendet.

alzaimar 20. Okt 2006 21:36

Re: Komma/Punkt Dezimalseperator
 
Luckie und Hansa bei ihren Ehestreitereien. Typisch für Freitagabend. :mrgreen:

Luckie 20. Okt 2006 21:42

Re: Komma/Punkt Dezimalseperator
 
Ich lasse mich scheiden. :mrgreen:

Hansa 20. Okt 2006 22:05

Re: Komma/Punkt Dezimalseperator
 
Zitat:

Zitat von Luckie
Ich lasse mich scheiden. :mrgreen:

Es ist entsetzlich. :shock: :zwinker: :gruebel: :wall: :mrgreen:

Bin von 2 Nachkommastellen (bzw. fester Anzahl) ausgegangen (siehe Bsp. 1,50). Wenn dem so ist, dann ist alles andere IMHO unnötig kompliziert und wohl auch windowsspezifisch. Falls nicht, dann wäre der Vorschlag tatsächlich zu einfach. Dann gäbe es aber eventuell auch noch eine weitere Fehlerquelle : 0,123456 und 123456E-6 sind dieselben Zahlen, oder ? Dann hätte man neben der ,. Geschichte auch noch das E und - für passendes real umzuwandeln. Na dann gute Nacht. :???:

Wie wäre es denn, selbst in diesem Fall bei Integer zu bleiben ? 2mal Ini.ReadInteger, was solls. Eine Ini-Zeile für Basis und eben noch eine für Exponent. Daraus errechne ich mir eine real-Variable die dann verwendet wird. Zeige ich sie an, dann so, wie Windows sie eben anzeigt. 8) Auch dann gäbs keinen Ärger mit Ländereinstellungen. Bei einem solchen Szenario (unbekannte Zahlengenauigkeit) kommen mir allerdings Bedenken, ob eine INI - Datei überhaupt der richtige Weg für so was ist.

mkinzler 20. Okt 2006 22:23

Re: Komma/Punkt Dezimalseperator
 
Was ist dem am Setzen des Dezimalseparators so kompliziert?

Hansa 20. Okt 2006 22:28

Re: Komma/Punkt Dezimalseperator
 
Weil möglichst komplizierte Fälle ins Spiel kamen. Von mir zuletzt die Zahl hier :

Zitat:

Zitat von Hansa
123456E-6

Siehst Du da einen Decimalseparator ? :mrgreen:

mkinzler 20. Okt 2006 22:36

Re: Komma/Punkt Dezimalseperator
 
Nein aber damit hat Delphi trotzdem kein Problem!

Hansa 21. Okt 2006 00:51

Re: Komma/Punkt Dezimalseperator
 
Mir fällt auf Anhieb die Funktion nicht ein, die die Exponential-Schreibweise konvertiert in ein XX,YY usw. Format. Wenn es die aber gibt, dann ist die Frage ja wohl vollständig gelöst. Deshalb bitte hier mal posten.

mkinzler 21. Okt 2006 08:51

Re: Komma/Punkt Dezimalseperator
 
Na StrToFloat oder besser TryStrToFloat

OldGrumpy 21. Okt 2006 15:19

Re: Komma/Punkt Dezimalseperator
 
@Hansa: Mal ganz einfaches Beispiel: Nen Taschenrechner, dem Du die Zahlen eingibst.

Du gibst ein: 1.500,267 und meinst damit Eintausendfünfhundertkommazwosechssieben.

Ein Amerikaner tippt die gleiche Zahl als 1,500.267 ein.

Und was machste nu um die Zahl aus dem Editfeld (die dann ja als String vorliegt) in eine Zahl zu konvertieren?
Dumm aus der Wäsche schauen :) Bzw. Dein Programm wandelt falsch oder wirft Fehler. Ich kann echt nicht verstehen, wie man sich gegen zwei zusätzliche Zeilen Code und vier zusätzliche Zeichen pro Aufruf sperren kann, mit dem Argument "überflüssiger Aufwand". Mit der Einstellung wirst Du nicht sehr weit kommen :) Spätestens wenn Du mal ein Programm schreibst, das nicht nur auf deutschen Rechnern laufen soll, wirst Du Dich echt noch umgucken. Und sowas passiert schneller als man denkt :)

Aber mach ruhig so weiter, Leute wie Du sichern meinen Lebensabend, insofern schonmal ein herzliches Danke :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:19 Uhr.

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