Fórum Problema com PChar #289292
24/07/2005
0
procedure TForm1.Button3Click(Sender: TObject);
var
strRes: PChar;
begin
try
strRes := StrAlloc(Length(Edit1.Text)+1);
strRes := TrataNomeP(PChar(Edit1.Text));
Edit2.Text := StrPas(strRes);
finally
StrDispose(strRes);
end;
end;
function TrataNomeP(strNome : PChar) : PChar;
{Devolve o strNome sem os conectivos (dos, das, do, da, e, etc.) presentes no arquivo conectivos.txt
entra JOSE DOS SANTOS DA SILVEIRA DE ALMEIDA E SOUZA
sai JOSE SANTOS SILVEIRA ALMEIDA SOUZA }
const
ESPACO : array [0..1] of char = ´ ´ + 0 ;
MAX_BUFFER = 81; //igual ao campo NOME no BD + 1
var
ptrPos : PChar;
strPedaco, strNomeComp : array [0..MAX_BUFFER] of char;
begin
if (strNome = ´´) or (StrLen(strNome) > MAX_BUFFER) then
exit;
strNome := AnsiStrLower(strNome);
ptrPos := AnsiStrPos(strNome, ´ ´);
strNomeComp := ´´;
while (ptrPos <> nil) do
begin
StrLCopy(strPedaco, strNome, StrLen(strNome) - StrLen(ptrPos));
// Conectivos é uma TStringList
if (Conectivos.IndexOf(string(strPedaco)) = -1) then
begin
StrCat(strNomeComp, strPedaco);
StrCat(strNomeComp, ESPACO);
end;
repeat //LTrim;
inc(ptrPos);
until ptrPos <> ´ ´;
strNome := ptrPos;
ptrPos := AnsiStrPos(strNome, ´ ´);
end;
StrCat(strNomeComp, strNome);
StrLCopy(strNome, strNomeComp, StrLen(strNomeComp));
Result := strNome;
end;
Executando passo-a-passo verifiquei que a rotina TrataNomeP faz o que se espera mas ao atribuir o resultado para strRes, tem um caracter estranho (em forma de um quadradinho) e quando vai copiar para o Edit2.Text dá o erro
e o compilador para na linha
SetString(Result, Buffer, LoadString(FindResourceHInstance(ResStringRec.Module^), ResStringRec.Identifier, Buffer, SizeOf(Buffer)))
da função LoadResString de System.pas
alguém sabe o que pode pode estar errado :?:
Observei que se o nome for pequeno (JOSE DOS SANTOS por exemplo) o erro não acontece.
A função tem que ser em PChar pois é para uma dll (depois de resolvido este problema).
Uso Delphi 5 e Win XP Pro
Grato
José Henrique
Curtir tópico
+ 0Posts
26/07/2005
Beppe
Se quer saber pq não se deve usar livremente, é devido ao uso errôneo que feaz dela. Por exemplo, vc aloca memória e joga para strRes. Depois perde a referência a ela atribuíndo novamente a strRes, invés de copiar a memória para o endereço já determinado.
Gostei + 0
26/07/2005
José Henrique
Não me abandone!!!
A função tem que usar PChar pois é para usar em uma dll (que será usada em outras ambientes)
Me indique o que está errado e como posso resolver, por favor!!
Tenho noção que ponteiro é um apontador (termos que alguns acadêmicos acham mais apropriado) para o endereço da memória onde ´começa´ a informação.
Gostei + 0
27/07/2005
Kapak
strNome := ptrPos; // Aqui vc perde a referência
StrLCopy(strNome, strNomeComp, StrLen(strNomeComp)); // Aqui vc não tem mais memória alocada p/ strNome
Então tente substituir:
StrLCopy(strNome, strNomeComp, StrLen(strNomeComp)); Result := strNome;
Result := StrAlloc(StrLen(strNomeComp)+1); // Aqui vc aloca memória p/ Result e libera após chamar a função StrLCopy(Result, strNomeComp, StrLen(strNomeComp));
Na chamada da função:
try strRes := StrAlloc(Length(Edit1.Text)+1); // Não deve ser alocada a memória pq a função já faz isto strRes := TrataNomeP(PChar(Edit1.Text)); Edit2.Text := StrPas(strRes); finally StrDispose(strRes); end;
try strRes := TrataNomeP(PChar(Edit1.Text)); Edit2.Text := StrPas(strRes); finally StrDispose(strRes); end;
Gostei + 0
27/07/2005
José Henrique
Fiz as alterações que você sugeriu e deu certo. Hoje entendo mais de PChar que antes deste post graças a vc e ao Beppe.
Obrigado :D
Gostei + 0
28/07/2005
Beppe
E geralmente é a maneira apropriada de se lidar com strings em diferentes linguagens. Mas o que deve ser PChar é apenas a interface, implemente usando o tipo string fornecido pela linguagem.
Dois exemplos de como usar PChar:
Internamente(manipulação com PChar por questões de performance)
function Bah(const S: String; Ch: Char): Integer; var P, Q: PChar; begin P := Pointer(S); Q := P + Length(S); Result := 0; while P < Q do begin if P^ = Ch then Inc(Result); Inc(P); end; end;
Externamente(conversão para PChar por necessidade)
function Bah(S: PChar; Ch: Char): Integer; external ´mydll.dll´; ... Bah(PChar(MinhaVariavelString), ´ ´);
Espero ter podido esclarecer as diferenças. É perfeitamente possível manter seu código atual(e se estiver rodando sem problemas, deixe assim mesmo), mas há a questão da praticidade.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)