Autor Téma: Textový súbor v ANSI kódovaní  (Přečteno 7392 krát)

Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Textový súbor v ANSI kódovaní
« kdy: 18-03-2014, 11:08:33 »
Snažím sa načítať do Lazarusu (v1.2.0) obyčajný textový súbor v ANSI kódovaní (pár riadkov). Žiaľ, neviem, ho dostať do Lazarusu bez poškodenia, stále namiesto znakov s diakritikou (napr. č, š, ť, á) dostávam otázniky v texte.
Skúsil som načítať súbor cez TFileStream, TStringList aj TMemo.
Viem, že Lazarus je silno orientovaný na UTF8, ale toto by hádam mohol zvládnuť. Alebo robím chybu ja?  :-[
Lazarus, Delphi - RQ Money

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #1 kdy: 18-03-2014, 11:18:04 »
Google tvrdi toto:
Strings.LoadFromStream(TDecodingStream.Create(TFileStream.Create('myfile'), '...', 'utf-8'));

Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Re:Textový súbor v ANSI kódovaní
« Odpověď #2 kdy: 18-03-2014, 14:12:14 »
Vďaka za nakopnutie, skúšam to (i keď zatiaľ bez úspechu). :(
Ak správne uvažujem, tak:
Strings = čokoľvek, čo podporuje funkciu LoadFromStrings (napr. TStrings, TMemo, ...)
TDecodingStream = TOwnerStream (to som našiel na webe)
TFileStream = TFileStream (ten sa nemení)
...
Nevadí, budem skúšať ďalej.
Lazarus, Delphi - RQ Money

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #3 kdy: 18-03-2014, 14:21:09 »
TFileStream muze byt zrejme zastoupen jakymkoliv steamem, jde o zdroj dat.
TDecodingStream je to, co te zajima - mel by provest prislusnou konverzi.
A ano, Strings bude tvoje Memo ... snad :)

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #4 kdy: 18-03-2014, 14:34:40 »
... aha ... zrejme pujde o "udelej si sam" funkci :)

ale kdyz udelas toto:
  Memo1.Lines.LoadFromFile('...');
  Memo1.Lines.Text:=UTF8Encode(Memo1.Lines.Text);
tak by se to melo zobrazit spravne
« Poslední změna: 18-03-2014, 14:42:57 od < z > »

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Textový súbor v ANSI kódovaní
« Odpověď #5 kdy: 18-03-2014, 18:22:07 »
... aha ... zrejme pujde o "udelej si sam" funkci :)

ale kdyz udelas toto:
  Memo1.Lines.LoadFromFile('...');
  Memo1.Lines.Text:=UTF8Encode(Memo1.Lines.Text);
tak by se to melo zobrazit spravne

<z>, prosím tě, neraď lidem podobné prasokódy, které jsou za a naprosto krutopřísně blbě a za b ještě k tomu nefungují...

----

Slavomíre, nejjednodušší pro tebe bude stáhnout si mojí OXml z http://www.kluug.net/oxml.php. Ta má mimo jiné tyto unity:
- OEncoding.pas: port TEncoding z Delphi 2009+ pro Lazarus a D6-2007.
- OTextReadWrite.pas: rychlé čtení stringů ze streamu s bufferem.

Pak ti stačí tento kód:

Kód: [Vybrat]
procedure TForm1.Button7Click(Sender: TObject);
var
  xFileStream: TFileStream;
  xReader: TOTextReader;
  S: String;
begin
  xFileStream := nil;
  xReader := nil;
  try
    xFileStream := TFileStream.Create('S:\test-ansi.txt', fmOpenRead or fmShareDenyNone);//vytvoř file stream
    xReader := TOTextReader.Create(xFileStream, TEncoding.ANSI);//vytvoř TOTextReader, použij kódování ANSI, pokud neexistuje BOM

    S := xReader.ReadString(High(Integer));//přečti kompletní soubor najednou

    //v S je uložen obsah souboru, dělej si s ním co chceš...
    ShowMessage(S);
  finally
    xReader.Free;
    xFileStream.Free;
  end;
end;
« Poslední změna: 18-03-2014, 18:30:44 od oxo »
Embarcadero Technology Partner

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #6 kdy: 18-03-2014, 21:01:11 »
s a) bych souhlasil, s b) zasadne souhlasit nemuzu - uz jen proto, ze funguji ;)

ale jinak ty OXml vypadaj dobre

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Textový súbor v ANSI kódovaní
« Odpověď #7 kdy: 18-03-2014, 23:00:44 »
s a) bych souhlasil, s b) zasadne souhlasit nemuzu - uz jen proto, ze funguji ;)
Tvůj kód v Lazarusu nefunguje... ;)

ale jinak ty OXml vypadaj dobre
Díky!
Embarcadero Technology Partner

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #8 kdy: 19-03-2014, 07:45:14 »
Tvůj kód v Lazarusu nefunguje... ;)


Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Re:Textový súbor v ANSI kódovaní
« Odpověď #9 kdy: 19-03-2014, 09:11:03 »
Ďakujem obidvom za radu.
To oxo: nie som až tak zbehlý, aby som si v tej hromade súborov od Teba našiel len to, čo potrebujem. Možno neskôr, keď zlyhajú iné spôsoby.
To <z>: podľa nákresu to funguje. Podľa Lazarusu nie.  :-[
Niečo iné je vložiť do TMemo nejaký ANSI text a potom to vedľa previesť do UTF8 a niečo iné použiť funkciu LoadFromFile. Možno sa mýlim, preto prikladám môj kód funkcie - udalosť na TMenuItem (+ náhľad obrázku + ANSI súbor na stiahnutie):


Kód: [Vybrat]
procedure TfrmMain.mnuOtvoritClick(Sender: TObject);
begin
if OpenDialog.Execute <> True then Exit;
If FileExists(OpenDialog.FileName) = True then begin
    memSprievodka.Lines.LoadFromFile(OpenDialog.FileName);
    memSprievodka.Lines.Text := UTF8Encode(memSprievodka.Lines.Text);
end;
end;

Tak netuším, kde robím chybu.
Lazarus, Delphi - RQ Money

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #10 kdy: 19-03-2014, 10:01:50 »
oxo ti to cele naserviroval ... staci do uses pouzit to OEncoding a frcis.

Muj blby napad neni vhodny prave proto, ze neni univerzalni a musis natvrdo prijit na to,
jak to spravne dekodovat. Zajimave je, ze me to funguje i s tvym souborem :)

muzes jeste vyzkouset toto?
AnsiToUtf8(AnsiString(memSprievodka.Lines.Text))

oxo me sice zabije, kdyz to uvidi :D

resp. mozna by bylo lepsi to udelat takto, aby ses vyhnul tem prasackym
nekontrolovatelnym konverzim

Kód: [Vybrat]
var
  txt: TextFile;
  textline: AnsiString;
begin
  AssignFile(txt, 'sprievodka.txt');
  Reset(txt);
  Repeat
  Readln(txt,textline);
  Memo1.Lines.Add(AnsiToUtf8(textline));
  Until EOF(txt);
  Closefile(txt);

A jeste jedna moznost
http://wiki.lazarus.freepascal.org/Theodp
... jeden soubor, je tam i priklad
« Poslední změna: 19-03-2014, 10:18:07 od < z > »

Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Re:Textový súbor v ANSI kódovaní
« Odpověď #11 kdy: 19-03-2014, 10:38:08 »
Citace
muzes jeste vyzkouset toto?
AnsiToUtf8(AnsiString(memSprievodka.Lines.Text))
Tak toto nefungovalo ani náhodou ... :D

Citace
resp. mozna by bylo lepsi to udelat takto, aby ses vyhnul tem prasackym nekontrolovatelnym konverzim ...
Tak toto našťastie fungovalo v poriadku!!! Jupí.  :) :) :)
Dúfam len, že spätne to pôjde nejak takto uložiť (v prípade zmeny v texte) zase naspäť do ANSI súboru bez problémov.
Srdečná vďaka za pomoc, < z > !!!
Je to predsa len jednoduchšie riešenie, ako navrhoval oxo.
Lazarus, Delphi - RQ Money

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Textový súbor v ANSI kódovaní
« Odpověď #12 kdy: 19-03-2014, 10:43:13 »
To oxo: nie som až tak zbehlý, aby som si v tej hromade súborov od Teba našiel len to, čo potrebujem. Možno neskôr, keď zlyhajú iné spôsoby.

Hmmm, jasně jsem ti napsal, co potřebuješ: OEncoding a OTextReadWrite. Stačí být dost zběhlý ve čtení... :)

----

< z >:
Kód: [Vybrat]
  Memo1.Lines.LoadFromFile('...');
  Memo1.Lines.Text:=UTF8Encode(Memo1.Lines.Text);

podobné kódy možná fungují u tebe, u mě a (podle jeho reakcí) u Slavomíra taky ne. Používáš tam implicitní konverze v rámci různých kódování, které se mohou na různých počítačích (system locale) chovat různě - a to i jako kompilovaný projekt... Takže ne-e, tak fakt ne.

A používat TextFile, to už je skoro předminulé století... :)
Embarcadero Technology Partner

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1145
  • Karma: 44
    • Verze Delphi: 7, 2010
Re:Textový súbor v ANSI kódovaní
« Odpověď #13 kdy: 19-03-2014, 11:00:23 »
Tak me to je jasny, ze se to bude chovat ruzne :)
Jen jsem nechtel brat bazuku na komara ...

Tak aby byli vsichni stastni
Kód: [Vybrat]
var
  s: AnsiString;
  m: TMemoryStream;
begin
  m:=TMemoryStream.Create;
  try
     // load
     m.LoadFromFile('test.txt');
     SetString(s, PAnsiChar(M.Memory), M.Size);
     Memo1.Lines.Text:=AnsiToUtf8(s);

     // save
     m.Clear;
     s:=Utf8ToAnsi(Memo1.Lines.Text);
     m.Write(Pointer(s)^, length(s));
     m.SaveToFile('test2.txt');
  finally
    m.Free;
  end;
end;

Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Re:Textový súbor v ANSI kódovaní
« Odpověď #14 kdy: 19-03-2014, 11:02:37 »
Citace
Hmmm, jasně jsem ti napsal, co potřebuješ: OEncoding a OTextReadWrite. Stačí být dost zběhlý ve čtení... :)
Máš pravdu, bolo to jasne napísané, ešte raz ďakujem za ponuku súborov.
Ale musiš uznať, že riešenie od < z > je krátke a aj pre mňa (laika) zrozumiteľné (a vôbec mi nevadí, že je to funkcia či premenná "z minulého storočia"). Hlavné je, že funguje.  ;)
Lazarus, Delphi - RQ Money