[Delphi/Lazarus] Problem z enterami

0

Piszę sobie mały edytorek do gry, którą planuję zrobić (gra typu quiz, potrzebuję łatwego sposobu do zrobienia pytań) i mam pytanie odnośnie Delphi/Lazarus (raczej tego drugiego, chociaż oba są podobne). Co do pytania, to mam TMemo i chcę wymusić określony format enterów. Chcę je mieć jako #10 (LF) nawet jeśli mój program będzie skompilowany w Windowssie, gdzie entery są #13 (CR) albo na maku gdzie kod entera to #13#10 (CRLF), z powodu mojej procedury konwertującej entery do \n dla łatwiejszego importu do mojego silnika. Alternatywnie moglibyście podać sposób na detekcję formatu enterów.

0

A koniecznie musisz wykrywać EOL? Enter pod Windowsem to #13#10, a pod Amigiami, Linuxami czy Unixami
to jak wiadomo #10. Jedyne co mogę doradzić to właśnie zamiana najpierw przy tworzeniu treści do plików na
przykład \n na #13#10, a później w programie przed pokazaniem danych zamiana: \n na: #13#10 i tak chyba
będzie najprościej. Do zamiany wykorzystaj funkcję StringReplace - powinna być ona chyba także w Lazarusie.

0
olesio napisał(a)

Nie wiem w czym problem. Enter pod WIndowsem to wiadomo #13#10, pod Amigiami, Linuxami czy Unixami
to jak wiadomo #10. Jedyne co mogę doradzić to właśnie zamiana najpierw przy tworzeniu treści do plików na
przykład \n na #13#10, a później w programie przed pokazaniem danych zamiana: \n na: #13#10 i tak chyba
będzie najprościej. Do zamiany wykorzystaj funkcję StringReplace - powinna być ona chyba także w Lazarusie.

No właśnie tak robię, tzn. z tą funkcją, ale nie chodzi o zamianę \n na entery tylko o operację odwrotną. Dlatego muszę wiedzieć jak wymusić określony typ entera w TMemo albo jak zrobić detekcję znaku enter.

Generalnie chodzi o to, aby to zadziałało bez żadnych modyfikacji niezależnie od tego czy skompiluję pod MacO$(ł)em, Window$em czy Linuksem.

Krótko: Poszukuję sposobu na wymuszenie określonego typu entera w TMemo (obojętnie czy CR, czy LF, czy CRLF) albo detekcję formatu entera tak abym mój kod zamiany zamieniał Entery na '\n' niezależnie od systemu.

0

Ja to rozwiązałem tak. Testowane na trzech formatach zapisu końca linii dokonanych w tej samej treści.
Zapis nastąpił pod edytorem wbudowanym w FileManager FAR (Shift+F2). Działa raczej ok, tylko trzeba
ładować do jakiegoś Streama, najlepiej TMemotyStream jak widzisz poniżej. Bo po załadowaniu pliku, do
TStringList, znak końca linii zmieniał się na #13#10. A i mam nadzieję, że moje rozwiązanie, Ci pasuje,
bo jak widzisz używając MemoryStreama w taki sposób jak pokazałem w Button1Click, można również w
łatwy sposób załadować tekst z TResourceStream, jeżeli swoje pytania będziesz trzymał w zasobach exe.
Teraz już nie potrzebujesz zamieniać linii na \n, tylko ustalać ją w edytorze, o ile ten na to pozwala i jęśli o to
Tobie chodziło, ale tak zrozumiałem. A do edycji plików tekstowych - polecam Ci FAR'a i wewnętrzny edytor.

//...
type
  TEOLChar = (ecUnknown, ecWindows, ecUnix, ecMac);

var
  ResultArr : array[TEOLChar] of string = ('UNKNOWN', 'Windows', 'Unix', 'Mac');

function WhatEOL(Text : string) : TEOLChar;
var
  X : Cardinal;
begin
  Result := ecUnknown;
  X := Pos(#13, Text);
  if X > 0 then
  begin
    if Text[X + 1] = #10 then
    begin
      Result := ecWindows;
    end
    else
    begin
      Result := ecMac;
    end;
  end
  else
  begin
    X := Pos(#10, Text);
    if X > 0 then
    begin
      Result := ecUnix;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender : TObject);
var
  S : string;
  MS : TMemoryStream;
begin
  OpenDialog1.Filter := 'Text files|*.txt';
  if OpenDialog1.Execute then
  begin
    S := OpenDialog1.FileName;
    OpenDialog1.InitialDir := ExtractFilePath(S);
    MS := TMemoryStream.Create;
    MS.LoadFromFile(S);
    SetLength(S, MS.Size);
    MS.Read(PChar(S)^, MS.Size);
    ShowMessage(ResultArr[WhatEOL(S)]);
    MS.Free;
  end;
end;
0

Dzięki, tak zrobię. Lazarus nie zmienia znaków końca linii (siedzę pod Linuksem i wszystko jest ok), a nawet jeśli, to i tak nie ma to znaczenia, bo i tak entery będą zmieniane na '\n'. Dzięki za kod, przyda mi się (po pewnych przeróbkach, żeby zwracał stringa ze znakiem końca linii, aby potem łatwo do StringReplace podstawić bez żadnych durnych ifów).

//edit: Dodaję kod zmienionej funkcji, jak by ktoś potrzebował.

function WhatEOL(Text : string) : string;
var
  X : Int64;
begin
  Result := '';
  X := Pos(#13, Text);
  if X > 0 then
  begin
    if Text[X + 1] = #10 then
    begin
      Result := #13+#10;
    end
    else
    begin
      Result := #13;
    end;
  end
  else
  begin
    X := Pos(#10, Text);
    if X > 0 then
    begin
      Result := #10;
    end;
  end;
end;

Przy okazji zmieniłem typ zmiennej X na Int64, aby można było pracować na naprawdę długich łańcuchach.

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