IT NEWS PC REVUE PC FORUM FreeBSDInternet time: @407
Obsah fóra
Pravidlá  •  Kontakt  •  Prihlásenie  •  Registrácia

Dokonalosť v jednoduchosti

Wyse T10 – dokonalosť, na ktorú ste čakali. www.ts.avnet.com

Zbavte sa viazanosti

Za Samsung Galaxy Ace so zlatým O2 Paušálom zaplatíte teraz 12 €! pausal.o2.sk

Bonus 50 € za prenos

čísla do O2 na ktorýkoľvek program s platbou na faktúru. V e-shope. www.o2.sk

Webhosting - akcia +9 mesiacov

K ročnému predplatnému až 9 mesiacov zadarmo pri prevode hostingu k nám. www.exohosting.sk

Spoločnosti Online s.r.o.

Ponúkame čisté spoločnosti. Obchodný register vybavíme za vás! www.spolecnostionline.cz

Dlhé retazce

Zaslať odpoveď
AutorSpráva
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: Ne 12.09.10 13:13Odpovedať s citátomNávrat hore

Dobrý den,
musím pracovat s dlhými retazcami typu pwidechar ale nemôžem zistit funkcie alebo metody ktoré s nimi pracuju, napr. ekvivalent Length, Write ( file_out, ansi_string) a pod. prosím o radu, kde by som sa to mohol dozvediet. V helpe som našiel iba deklarácie. Vdaka.
Zobraziť informácie o autoroviOdoslať súkromnú správu
coldak
Skúsený užívateľ
Skúsený užívateľ

Založený: 29.10.2008
Príspevky: 936

PríspevokZaslal: Ne 12.09.10 15:24Odpovedať s citátomNávrat hore

a odkial mas ze Length nefunguje aj pre PWideChar ?
Zobraziť informácie o autoroviOdoslať súkromnú správu
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: Ne 12.09.10 19:16Odpovedať s citátomNávrat hore

Zdravim,
túto konkretne som netestoval, ale ked mám vytvoreny subor file_out ako file a chcem zapísat hodnotu do suboru prikazom write , tak mi vypise chybu pri zapise o nekorektnosti typov.
Neviem ci je problem v type parametra pre write alebo mam hladat niekde inde.
Vdaka.
Zobraziť informácie o autoroviOdoslať súkromnú správu
coldak
Skúsený užívateľ
Skúsený užívateľ

Založený: 29.10.2008
Príspevky: 936

PríspevokZaslal: Ne 12.09.10 19:27Odpovedať s citátomNávrat hore

hod sem konkretny kus problemoveho kodu, cize ako declarujes premennu , ako ju naplnas a ako sa ju snazis zapisat do suboru
Zobraziť informácie o autoroviOdoslať súkromnú správu
Fico
Skúsený užívateľ
Skúsený užívateľ

Založený: 11.01.2009
Príspevky: 1049

PríspevokZaslal: Ne 12.09.10 22:25Odpovedať s citátomNávrat hore

Skôr, ako začneš pracovať s týmto dátovým typom, by si sa s ním mal trocha oboznámiť, aby ti to uľahčilo prácu. Ak si pracoval s klasickým stringom, tak si možno zaregistroval dátový typ PChar. Je to vlastne smerník na prvý znak v reťazci (string). Príklad:

kód:
  s: string;
  c: PChar;
// ...
  s:= 'Toto je klasicky reťazec';
  c:= @s[1];
  ShowMessage( 'Výpis reťazca pomocou smerníka: ' + c );


To isté platí aj pre dátový typ PWideChar. Ty ho nemôžeš použiť samostatne. Je to smerník, ktorý musí ukazovať na typ WideChar (prípadne pole 2-bajtových prvkov), teda na prvý znak vo wide reťazci (WideString). Príklad:

kód:
  s: WideString;
  p: PWideChar;
// ...
  s := 'Velmi dlhy retazec';
  p := @s[1];
  ShowMessage( 'Výpis reťazca pomocou smerníka: ' + p );


Takže po dávke teórie príklad na zápis premennej typu WideString (nie PWideChar, pretože to je smerník) do súboru pomocou streamu:

kód:
procedure TForm1.Button1Click(Sender: TObject);

var f: TFileStream;
    hlavicka: array[0..1] of byte;
begin

  s := 'Velmi dlhy retazec';
  p := @s[1];

  hlavicka[0] := $FF;
  hlavicka[1] := $FE;

  f := TFileStream.Create( 'E:\skuska.txt', fmCreate OR fmOpenWrite );
  try
    f.WriteBuffer( hlavicka, 2 );
    f.WriteBuffer( p^, length(p) * 2);
  finally
    f.Free;
  end;

end;


Ešte drobné vysvetlenie: WideString používa UNICODE kódovanie, ktoré v súbore určuje hlavička začínajúca hodnotami 0xFF 0xFE. Každý znak v UNICODE zaberá dva bajty, nie jeden, preto je pri určení dĺžky buffera dvojnásobná dĺžka reťazca.

(*
To bol jednoduchý príklad. Ak používaš dlhé reťazce, možno ti bude výhodnejšie zadeklarovať dynamické pole WideChar znakov, pričom veľkosť si budeš manuálne zväčšovať podľa potreby a postupne znak po znaku ukladať do tohto poľa. Potom by si smerník PWideChar priradil na prvý prvok tohto poľa.
*)
Zobraziť informácie o autoroviOdoslať súkromnú správuICQ
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: Ut 14.09.10 23:09Odpovedať s citátomNávrat hore

Dakujem za doterajšie odpovede, poučilo som sa ale na skúšobnom príklade mi dáva výnimku EInvalidPointer pri Freemem. Neviem čo robím zle, vdaka za usmernenie.Prikladám proceduru

procedure TForm1.Button1Click(Sender: TObject);

var
myWideString : WideString;
myWideCharPtr : PWideChar;
i : integer;

begin
myWideString := 'hallo';
myWideCharPtr := Addr(myWideString[1]);

GetMem(myWideCharPtr, Length(myWideString)+1*SizeOf(WideChar));
I:=0;
try
while i<= Length(myWideString) do
begin
StringToWideChar(myWideString, myWideCharPtr,Length(myWideString)+1);
showmessage ('gggg'+myWideCharPtr^);
Inc(i);
showmessage('incre '+inttostr(i));
Inc(myWideCharPtr,2);
end;
finally
FreeMem (myWideCharPtr);
end;
end;
Zobraziť informácie o autoroviOdoslať súkromnú správu
Fico
Skúsený užívateľ
Skúsený užívateľ

Založený: 11.01.2009
Príspevky: 1049

PríspevokZaslal: St 15.09.10 9:07Odpovedať s citátomNávrat hore

V riadku:
kód:
StringToWideChar(myWideString, myWideCharPtr,Length(myWideString)+1);

si prepísal adresu v myWideCharPtr a pri dealokovaní je potom nekorektný údaj. Okrem toho prvý parameter funkcie StringToWideChar je typu string - príklad.
Zobraziť informácie o autoroviOdoslať súkromnú správuICQ
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: St 15.09.10 9:53Odpovedať s citátomNávrat hore

Vdaka za odpoved, zmenil som program ale určite nie úplne dobre lebo teraz mi hlási AccessViolation na kernel32.dll, môžem poprosit o zhovievavost ?

procedure TForm1.ConvTXTUTF16x;

var
Str_in : char;
str_ins : string ;
Str_out : Widestring;
PStr_out : PWidechar;

Position : LongInt;

begin
Position := 1;
while not eof (FileInx) do
begin
Read (FileInx, Str_in);
Str_ins := Str_in;

PStr_out := Addr (Str_out[1]);
StringToWideChar ( Str_ins, PStr_out, Length (Str_ins)+ 1) ;
// BlockWrite (FileOutx, Str_out, 2);
Inc (Position);
ConvertForm.Gauge1.Progress := Position * 100 div Subor_Length;
Application.ProcessMessages;
end;
ConvertForm.Button1.Caption := 'Konverzia ukonèená';

end;
Zobraziť informácie o autoroviOdoslať súkromnú správu
Fico
Skúsený užívateľ
Skúsený užívateľ

Založený: 11.01.2009
Príspevky: 1049

PríspevokZaslal: St 15.09.10 11:07Odpovedať s citátomNávrat hore

AccessViolation ti hlási, lebo smerník PStr_out si priradil prázdnej premennej:
kód:
PStr_out := Addr (Str_out[1]);   // Str_out nema nastavenu velkost, teda nema ziaden znak


Upravil som tvoj kód takto (odstránil som z neho signalizačné prvky, aby som to skompiloval, tak si to ešte doplň naspäť):

kód:
procedure TForm1.Button1Click(Sender: TObject);
var
  Str_in : char;
  str_ins : string ;
  memAlloc: pointer;
  PStr_out : PWidechar;

begin


  AssignFile( FileInx, 'E:\skuska.txt' );
  Reset( FileInx );

  GetMem( PStr_out, FileSize( FileInx ) * sizeOf(WideChar) + 1 );   // rezervuj pamat velkosti suboru v bajtoch * 2 + nulovy znak
  memAlloc := PStr_out;                 // zalohuj pointer, lebo sa bude menit

  while not eof ( FileInx ) do begin

    Read (FileInx, Str_in);
    Str_ins:= Str_in;
    StringToWideChar( Str_ins, PStr_out, Length (Str_ins)+ 1) ;
    inc( PStr_out );   // posunieme sa na dalsi znak

    Application.ProcessMessages;

  end;

  PStr_out^ := WideChar(0); // na koniec nulovy znak
  PStr_out := memAlloc;     // adresa prveho znaku

//  ShowMessage( PStr_out );

  CloseFile( FileInx );
  FreeMem( memAlloc );      // uvolni pamat

end;


Poznámka: V kóde som použil funkciu FileSize na získanie veľkosti súboru. Tá sa ale nedá použiť pri TextFile súboroch. Premennú FileInx som zadefinoval ako File of Char, keďže sa z neho čítaju iba znaky. Nezabudni aj na to, že RAM ti klesne po spustení tohto kódu 2-krát viac, ako je veľkosť čítaného súboru.
Zobraziť informácie o autoroviOdoslať súkromnú správuICQ
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: St 15.09.10 14:31Odpovedať s citátomNávrat hore

Dakujem Ficovi, perfektne to funguje, musím si riadne pozriet teoriu smerníkov. Ak by som mohol, poprosím ešte o zápis 2 bytov, ktoré sú výsledkom volanej funkcie, do súboru. Výstupný súbor som otváral iba ako file, preto BlockWrite, ale tento spôsob a aj ked ho vytvorím ako file of char mi vyhadzuje chybu, lebo parameter write má byt ansi a ja zapisujem widechar. Velká vdaka.
Zobraziť informácie o autoroviOdoslať súkromnú správu
coldak
Skúsený užívateľ
Skúsený užívateľ

Založený: 29.10.2008
Príspevky: 936

PríspevokZaslal: St 15.09.10 14:46Odpovedať s citátomNávrat hore

a skusal si subor definovat ako file of widechar ?
Zobraziť informácie o autoroviOdoslať súkromnú správu
chrono
Skúsený užívateľ
Skúsený užívateľ

Založený: 13.11.2007
Príspevky: 808

PríspevokZaslal: St 15.09.10 16:32Odpovedať s citátomNávrat hore

Fico napísal:
Ešte drobné vysvetlenie: WideString používa UNICODE kódovanie, ktoré v súbore určuje hlavička začínajúca hodnotami 0xFF 0xFE. Každý znak v UNICODE zaberá dva bajty, nie jeden, preto je pri určení dĺžky buffera dvojnásobná dĺžka reťazca.
Unicode kódovanie neexistuje (teda aspoň ja žiadne také nepoznám). Je to len nezmysel, ktorý možno použil Microsoft (a možno to neboli ani oni, ale používa sa to vo Windows). V skutočnosti ide o kódovanie UCS2 alebo UTF-16 (už netuším, presne ktoré kódovanie sa tam používa).
Zobraziť informácie o autoroviOdoslať súkromnú správu
Fico
Skúsený užívateľ
Skúsený užívateľ

Založený: 11.01.2009
Príspevky: 1049

PríspevokZaslal: St 15.09.10 18:54Odpovedať s citátomNávrat hore

jasug napísal:
Ak by som mohol, poprosím ešte o zápis 2 bytov, ktoré sú výsledkom volanej funkcie, do súboru

Skús to tak, ako napísal Coldak, prípadne v totmo príspevku som ti napísal jedno riešenie.

chrono napísal:
Unicode kódovanie neexistuje (teda aspoň ja žiadne také nepoznám). Je to len nezmysel, ktorý možno použil Microsoft (a možno to neboli ani oni, ale používa sa to vo Windows). V skutočnosti ide o kódovanie UCS2 alebo UTF-16 (už netuším, presne ktoré kódovanie sa tam používa).

UNICODE zahŕňa viacero spôsobov kódovaní. Nevedel som presne, ktoré sa tu používa, preto som to napísal všeobecne, že používa UNICODE kódovanie.
Zobraziť informácie o autoroviOdoslať súkromnú správuICQ
jasug
Užívateľ
Užívateľ

Založený: 05.09.2008
Príspevky: 47

PríspevokZaslal: Št 16.09.10 17:29Odpovedať s citátomNávrat hore

Dakujem Ficovi, syntakticky to perfektne funguje, ale mám dve otázky:
ako viem rozlíšiť UTF16, UTF16M a pod. a ako si môžem fyzicky overiť či vytvorený kod je správny napr cez ftp: alebo niečo podobné. Dakujem.
Zobraziť informácie o autoroviOdoslať súkromnú správu
Fico
Skúsený užívateľ
Skúsený užívateľ

Založený: 11.01.2009
Príspevky: 1049

PríspevokZaslal: Št 16.09.10 22:32Odpovedať s citátomNávrat hore

Troška priblíž tvoje otázky. Rozlíšiť, aké je kódovanie reťazca v premennej WideString? Ak si myslel to, tak som vygooglil, že tá používa UTF-16 kódovanie.
Zobraziť informácie o autoroviOdoslať súkromnú správuICQ
Zobraziť príspevky z predchádzajúcich:    
Zaslať odpoveď
Nemôžete pridávať nové témy do tohto fóra.
Nemôžete odpovedať na témy v tomto fóre.
Nemôžete upravovať svoje príspevky v tomto fóre.
Nemôžete mazať svoje príspevky v tomto fóre.
Nemôžete hlasovať v tomto fóre.

Powered by phpBB 2.x.x © 2005 - 2012 PCforum, webhosting by WebSupport, edited by JanoF

SEO - optimalizácia pre vyhľadávače

Freebsd