WideString Versus Strings .. Diferença prática

Delphi

30/03/2006

Tenho observado no delphi 7 a defição de lagumas funçoes que aparentemente fazem a mesma ´coisa´ que as funçoes do delphi 5.0 . Porem usam um tipo difernte

Exemplo:

WideUpperCase(const S: WideString): WideString;

Versus

function AnsiUpperCase(const S: string): string;

o efeito prático é o mesmo :cry: ...
Para que essa definição de WideString ???
Ocupa mais Espaço na memória ??? Qaundo devemos começar a usar esses tipo de dados ???

Obrigado..


Marco Salles

Marco Salles

Curtidas 0

Respostas

Massuda

Massuda

30/03/2006

WideString está relacionado com textos em UNICODE.

Unicode é uma outra convenção usada paa codificar caracteres que, ao invés de se limitar a 256 caracteres, suporta até 65535 (ou 65536?) caracteres. Um caractere Unicode ocupa dois bytes e, por conveniencia, os 256 primeiros caracteres correspondem aos caracteres usuais.

Os caracteres adicionais servem para acomodar os diferentes idiomas (chines, russo, etc).


GOSTEI 0
José Henrique

José Henrique

30/03/2006

suporta até 65535 (ou 65536 ?)


65536 caracteres, de 0 a 65535.


GOSTEI 0
Ipc$

Ipc$

30/03/2006

WideString está relacionado com textos em UNICODE. Unicode é uma outra convenção usada paa codificar caracteres que, ao invés de se limitar a 256 caracteres, suporta até 65535 (ou 65536?) caracteres. Um caractere Unicode ocupa dois bytes e, por conveniencia, os 256 primeiros caracteres correspondem aos caracteres usuais. Os caracteres adicionais servem para acomodar os diferentes idiomas (chines, russo, etc).
Mas isso não quer dizer que uma WideString suporta até 65536; pq ela suporta igual a uma String (4 bytes a 2GB).


GOSTEI 0
Massuda

Massuda

30/03/2006

[quote:34d57d70a1=´ipc$´]Mas isso não quer dizer que uma WideString suporta até 65536; pq ela suporta igual a uma String (4 bytes a 2GB).[/quote:34d57d70a1]Eu não estava me referindo ao tamanho da string, mas sim ao total de símbolos que um caractere Unicode pode representar.


GOSTEI 0
Marco Salles

Marco Salles

30/03/2006

Obrigado a todos pela participação .. Mas porque da esta diferença grande

Veja definição de duas funçoes , que praticamente são ´iguias´

function WideFormat(const Format: WideString; const Args: array of const): WideString; overload;
function WideFormat(const Format: WideString; const Args: array of const; const FormatSettings: TFormatSettings): WideString; overload;


function Format(const Format: string; const Args: array of const): string; overload;
function Format(const Format: string; const Args: array of const; const FormatSettings: TFormatSettings): string; overload;


Mas na prática da uma diferença que não estou conseguindo entender

Vejam :

[b:dbe303b854]showmessage(WideFormat(´¬8.2f´, [123.456])); //retorna 12 :?: :?:
showmessage(Format(´¬8.2f´, [123.456]));[/b:dbe303b854] //retorna 12,46

:?: :?: :?: :?: :?:


GOSTEI 0
Massuda

Massuda

30/03/2006

[quote:6818d6765d=´Marco Salles´]...definição de duas funçoes , que praticamente são ´iguias´[/quote:6818d6765d]Format assume que cada caractere na string ocupa um único byte enquanto WideFormat assume dois bytes por caractere, seguindo o padrão Unicode.

[quote:6818d6765d=´Marco Salles´]...showmessage(WideFormat(´¬8.2f´, [123.456])); //retorna 12[/quote:6818d6765d]ShowMessage não sabe tratar WideStrings, provavelmente está truncando a string (Unicode) retornada por WideFormat no quinto byte e não no quinto caractere, já que ShowMessage assume implicitamente que um caractere = um byte enquanto WideFormat está assumindo que um caractere = dois bytes.


GOSTEI 0
Marco Salles

Marco Salles

30/03/2006

sinceramente , se me permite a replica massuda , eu não sei se é o showmessage que não esta preparado para o Wideformat ou se é o format que não esta preparado para variaveis do tipo WideString

Veja um detalhe curioso

var
TextString:String;
textoWide:WideString;
i:integer;
begin
textoString:=Format(´¬8.2f´,[12,345]);
textoWide:=WideFormat(´¬8.2f´,[12,345]);
for i:=1 to length(texto)
begin
showmessage(textoString[i]);
showmessage(TextWide[i]);
end;
end;


Voce vera que o TextWide tem o tamanho de ´oito´ igualzinho ao TextString , so que ele[b:66dac53843] dispoe [/b:66dac53843]os caracters de uma maneira esquisita
textoString[1] = ´´ textoWide[1]:=´´
textoString[2] = ´´ textoWide[2]:=´´ textoString[3] = ´´ textoWide[3]:=´´ textoString[4] = ´1´ textoWide[4]:=´´ textoString[5] = ´2´ textoWide[5]:=´´ textoString[6] = ´,´ textoWide[6]:=´´ textoString[7] = ´3´ textoWide[7]:=´1´ textoString[8] = ´5´ textoWide[8]:=´2´


[b:66dac53843]engraçado que
textoWide:=WideFormat(´¬2.5f´,[12,345]); apresenta 12,34 , Houve uma inversão da parte que cabe ao decimal com o tamanho da string... Mas se aproxima da realidade.. Isto parece que não esta documentado .. A unica diferença alem da inversão é que não esta arredondando[/b:66dac53843]

Por exemplo WideFormat(´¬2.5f´,[12,345]) = Format(´¬5.2f´,[12,345]) com exceção do Arredondamento , pois WideFormat(´¬2.5f´,[12,345]) --retorna 12,34 Format(´¬5.2f´,[12,345]) -->> retorna 12,35


:idea: :idea: :idea:
Fiz um pequeno exemplo par que possas entender melhor a quem interressar o que estou falando

procedure TForm1.Button7Click(Sender: TObject);
var
texto1:String;
texto2,texto3:WideString;
a2,a3,i:integer;  //a2 seria a parte decimal ; a3 seria o tamanho da String
a1:Extended;
begin
if trystrtofloat(edit1.text,a1) then
  begin
    //numero de casas decimais
    if trystrtoint(edit2.Text,a2) then
      begin
         //Tamanho
        if trystrtoint(edit3.Text,a3) then
          begin
            listBox1.Clear;
            listBox2.Clear;
            listBox3.Clear;
            texto1:=Format(´¬*.*f´, [a3,a2, a1]);
            texto2:=WideFormat(´¬*.*f´, [a3,a2,a1]);
            //note a inversão da parte decimal com o tamanho da String
            texto3:=WideFormat(´¬*.*f´, [a2,a3,a1]);
            showmessage( texto1+´ Tamanho : ´+inttostr(length(texto1+13+
                                 texto2+´ Tamanho : ´+inttostr(length(texto2)+13+
                                 texto3+´ Tamanho : ´+inttostr(length(texto3)));
            for i:=1 to length(texto1) do
               listbox1.items.add(texto1[i]);
            for i:=1 to length(texto2) do
               listbox2.items.add(texto2[i]);
            for i:=1 to length(texto3) do
               listBox3.Items.Add(texto3[i]);
         end
       else
        begin
          showmessage(´ATENÇÃO : Valor Incorreto.. Digite o Tamanho no edit3´);
          edit3.setfocus;
        end;
     end
    else
      begin
        showmessage(´ATENÇÃO : Valor Incorreto..Digite as casas decimais´);
        edit2.SetFocus;
      end
  end
else
 begin
   showmessage(´ATEÇÃO : para este procedimento digite´+13+
   ´               um Numero "Real" válido no Edit1´);
   edit1.setfocus;
 end;
end;


abraços...


GOSTEI 0
Massuda

Massuda

30/03/2006

Sobre os problemas com WideFormat... dei uma pesquisada e descobri que esse é um [url=http://qc.borland.com/wc/qcmain.aspx?d=4254]bug[/url] presente em todas versões do Delphi anteriores ao Delphi 2005.

O suporte a Unicode do Delphi sempre foi considerado precário (tem rotinas que suportam Unicode, mas a VCL não suporta Unicode).

Caso você tenha real necessidade de usar Unicode (vai exportar software para a Europa Oriental ou países asiáticos?), existem os componentes da [url=http://www.tntware.com/delphicontrols/unicode/]TntWare[/url] (freeware com fontes) e um biblioteca de funções para lidar com WideString´s da [url=http://www.soft-gems.net/UnicodeLibrary.php]Soft-Gems[/url] (open source).


GOSTEI 0
POSTAR