Liczby rzeczywiste: kropka czy przecinek

0

Witam
byc moze jest to banalny problem ale ja nie mam
pomyslu jak go rozwiazac...

program wykonuje obliczenia i zapisuje ich wyniki do plikow TEKSTOWYCH
jakis czas potem tez je wczytuje.

Ten sam program jest uruchamiany z roznych komputerow
(kozystajac z tych samych plikow)

I tu pojawia sie problem...
na roznych komputerach sa rozne ustawienia lokalne
tak ze czasem liczby rzeczywiste pisane sa z kropka(.) a czasem z przecinkiem(,)
no i jak zapisze plik z kropkami(.) a potem sprobuje odczytac uzywajac przecinkow(,)
to mi program sie wiesza:(

JAK TO OBEJSC??????
nie mam mozliwosc zmiany ustawien na wszystkich komputerach:/

0

no faktycznie masz banalny problem...
mozesz uzyc albo plikow ini (chociaz domyslam sie, ze w Twoim przypadku nie bedzie to najlepsze rozwiazanie)...
albo (najlepiej):
przy ladowaniu pliku, przy wczytywaniu tekstu zamieniasz w nim wszystkie kropki na przecinki czy tam na odwrot...:
jak juz wszytasz text zalozmy do np. Memo1 to dajesz:

procedure TForm1.Button1Click(Sender: TObject);
var S:String;
begin
S:=Memo1.Lines.Text;
S:=StringReplace(S, ',', '.', [rfReplaceAll]);
Memo1.Lines.Text:=S;
end;

lub w duzym skrocie, bez zmiennych:

Memo1.Lines.Text:=StringReplace(Memo1.Lines.Text, ',', '.', [rfReplaceAll]); //zamiani przecinki na kropki

pozdro [soczek]

0

Moja sugestia w module SysUtils jest DecimalSeparator i on decyduje co jest separatorem dziesiętnym.
I przy używaniu StrToFloat a nie wykluczone że także read(konsola) będzia wszystko dobrze działać.

0

W pliku WIN.INI znajduje się stała LOCALE_SDECIMAL, która przechowuje aktualny separator dziesiętny.
Takiej funkcji uzywałem do konwersji przecinka na kropkę:

{ zamiana ',' na '.' }
FUNCTION Koma(s :STRING) :STRING;
BEGIN
 WHILE Pos(',', S) > 0 DO
  S[Pos(',', S)] := '.';
  Koma:=s;
END;
0

Po co do tego pętla? StringReplace w zupełności wystarczy :| // fakt faktem, że wykonuje on też pętlę po elementach napisu, ale kod jest czystszy :>

0

Poza tym wartość Pos(',', S) jest obliczana dwukrotnie w czasie iteracji - IMHO marnotrawstwo czasu. A tak właściwie to próbujecie wyważyć otwarte drzwi - jak napisał dj, w module SysUtils jest DecimalSeparator. Klepnąć F1 i zobaczyć, do czego to służy.

0

jestem pełen podziwu dla propozycji wczytania najpierw całego pliku i zamieniania kropek na przeciniki. Czy to pętlą czy StringReplace. No po prostu bosko :/
Jedynie zdaje się, że dj zastanowił się przez chwilę. Jednak jak dla mnie nie jest to rozwiązanie 100% bo jak zmieni się wartośc zmiennej DecimalSeparator to zmieni się też format wyświetlania liczby i w ekstremalnych przypadkach trzeba by robić tak

  • wczytać liczbę jako string
  • zmienić DecimalSeparator na '.' (albo na ',')
  • przekonwertować string to float
  • zmienić DecimalSeparator na ',' (albo na '.')
  • wyświetlić liczbę (np po przemnożeniu)
  • następna liczba
    najlepiej będzie tu zastosować drugi wariant funkcji StrToFloat
    function FloatToStr(Value: Extended; const FormatSettings: TFormatSettings): string;

gdzie całość będzie wyglądała tak

var
  fs: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fs);
  fs.DecimalSeparator := ','; //albo '.'
  d := StrToFloat(str, fs);
end;

na dobrą sprawę nie trzeba pobierać do zmiennej fs ustawień domyślnych, ale możemy zechcieć z niej skorzystać jeszcze gdzie indziej i może się okazać, że zapomnieliśmy przypisać do któregoś pola tego rekordu odpowiedniego formatu

1 użytkowników online, w tym zalogowanych: 0, gości: 1