Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi PCHarReplace (https://www.delphipraxis.net/35668-pcharreplace.html)

Garby 10. Dez 2004 14:45


PCHarReplace
 
Hallo,

hat jemand eine Funktion zur Hand, die das gleiche mit PCHars macht, wie StringReplace mit Strings?

Danke
Garby

Manne 10. Dez 2004 14:55

Re: PCHarReplace
 
Nicht getestet müsste aber funktionieren.
(hab eine Min. bei Google suchen müssen)
Code:
function ReplaceCharFast (const s: string;
  ch1: char; ch2: char): string;
var i: integer;
begin
  Result := s;
  for i := 1 to length (Result) do
    if Result [i] = ch1 then
      Result [i] := ch2;
end;

Garby 10. Dez 2004 14:59

Re: PCHarReplace
 
Hallo,

vielleicht habe ich mich nicht klar genug ausgedrückt.
Ich muss in einer Zeichenkette bestimmte Teilzeichenketten duch neue Zeichenketten ersetzen.
Diese Zeichenketten müssen variabler Länge sein.

Deine Funktion arbeitet mit Chars.

Danke

Dani 10. Dez 2004 15:00

Re: PCHarReplace
 
Hi,
sind Strings und PChars nicht zuweisungskompatibel?

Dax 10. Dez 2004 15:02

Re: PCHarReplace
 
Strings musst du erst zu PChar casten, aber umgekehrt geht es ohne Probleme/Casts. ;)

Garby 10. Dez 2004 15:07

Re: PCHarReplace
 
Genau diesen Cast zu String möchte ich aber vermeiden.

Weiß sonst noch jemad was?

Garby

Luckie 10. Dez 2004 15:39

Re: PCHarReplace
 
Was spricht gegen den Cast?

Garby 10. Dez 2004 15:47

Re: PCHarReplace
 
..dass im PChar Binärdaten stehen, die durch einen Typecast verändert werden.
Oder sehe ich das falsch?

Luckie 10. Dez 2004 15:49

Re: PCHarReplace
 
Nicht das ich wüßte. Ein PChar ist einfach nur ein nullterminierender String.

Garby 10. Dez 2004 16:15

Re: PCHarReplace
 
Vielleicht kurz etwas zum Hintergrund.

Ich entwickle eine DB-Komponente für Mysql.
Dazu verwende ich die libmysql.dll und es funktioniert alles gut.

Das einzige Problem sind BLOBS.
Ich habe eine Komponente, die in einem BLOB Feld Binärdaten speichern will.
Bisher habe ich intern alles über Strings gehandelt, aber leider funktioniert das nicht mit dieser Komponente.

aus der OH der Komponente:
Zitat:

...the database field must have BINARY type (i.e. must have ability to store arbitrary binary data, without conversion and filtering of characters).

Using MEMO is not recommended and impossible, if you want to save Unicode, controls, pictures and tables in binary mode
Das Problem ist auch, dass bei einer Umwandlung nach String zwar Daten gespeichert werden, aber total falsch;

Ich füge die Daten direkt über einen INSERT befehl mittels der Funktion mysql_real_query in die DB ein.
Diese Funkton erwartet einen PChar als SQL String.

Also irgendwie muss das doch funktionieren, oder wie machen das andere :?

Danke
Garby

Garby 13. Dez 2004 08:37

Re: PCHarReplace
 
keiner eine Idee?

Nothine 13. Dez 2004 21:09

Re: PCHarReplace
 
hab so ne PChar-variante von StringReplace mal selber gemacht, kannst es dir ja mal ansehen
Delphi-Quellcode:
uses SysUtils;

...

function StrLen(P: PChar): Cardinal;
asm //nachgeproggt da die SysUtils-variante bei mir nicht geht
  PUSH ECX
  MOV ECX,-$01
@@Loop:
  INC ECX
  CMP BYTE PTR [EAX+ECX],$00
  JNZ @@Loop
@@End:
  MOV EAX,ECX
  POP ECX
end;

function StrLenE(P: PChar): Cardinal;
asm //das ist ein +1 im delphi-code weniger ;-D
  CALL StrLen
  INC EAX
end;

function StrCount(P: PChar; SubStr: PChar): Cardinal;
asm
  PUSH -$01
  PUSH EAX
  MOV EAX,EDX
  CALL StrLen
  XCHG DWORD PTR [ESP],EAX
@@Loop:
  CALL StrPos
  INC DWORD PTR [ESP+$04]
  ADD EAX,DWORD PTR [ESP]
  CMP EAX,DWORD PTR [ESP]
  JNE @@Loop
  ADD ESP,$04
  POP EAX
end;

function StrPosInt(P1,P2: PChar): Cardinal;
asm //die variante für leute die lieber zahlen als pointer mögen
  PUSH EBX
  MOV EBX,EAX
  DEC EBX
  CALL StrPos
  TEST EAX,EAX
  JZ  @@End
  SUB EAX,EBX
@@End:
  POP EBX
end;

function StrUpper(P: PChar): PChar;
asm //nachgeproggt da die SysUtils-variante bei mir nicht geht
  PUSH ESI
  PUSH EDI
  MOV  ESI,EAX
  CALL StrLenE
  CALL AllocMem
  MOV  EDI,EAX
  PUSH EAX
@@Loop:
  CMP  BYTE PTR [ESI],$00
  JZ   @@End
  LODSB
  CALL UpCase
  STOSB
  JMP  @@Loop
@@End:
  POP  EAX
  POP  EDI
  POP  ESI
end;

function PCharReplace(Source,OldStr,NewStr: PChar; Flags: TReplaceFlags): PChar;
var I: Cardinal;
    P: PChar;
begin
  P := AllocMem(
     StrLen(Source) -
    (StrLen(OldStr)*StrCount(Source,OldStr)) +
    (StrLen(NewStr)*StrCount(Source,OldStr)) + 1);
  Result := P;
  while Source^ <> #00 do begin
    if rfIgnoreCase in Flags then
      I := StrPosInt(StrUpper(Source),StrUpper(OldStr))
    else
      I := StrPosInt(Source,OldStr);
    if I = 0 then
      I := StrLenE(Source);
    StrMove(P,Source,I-1);
    Inc(P,I-1);
    Inc(Source,I-1);
    if Source^ <> #00 then begin
      StrMove(P,NewStr,StrLen(NewStr));
      Inc(P,StrLen(NewStr));
      Inc(Source,StrLen(OldStr));
      if not (rfReplaceAll in Flags) then begin
        StrMove(P,Source,StrLenE(Source));
        Break;
      end;
    end;
  end;
end;

SirThornberry 13. Dez 2004 21:50

Re: PCHarReplace
 
bekommst du bei der Funktion wenigstens auch die Länge des blobs? Ansonsten ist es völlig irsinnig, denn sobald eine #0 in dem Blob vorkommt würde an der stelle der blob als beendet angesehen werden.

Garby 14. Dez 2004 08:48

Re: PCHarReplace
 
Danke erstmal für den Post.

Allerdings hat SirThornberry recht.
Das Problem ist, dass ich mir nicht sicher sein kann, ob #0 Chars im PChar enthalten sind.

Die Länge des Blobs ist bekannt.
Könnte man damit die Funktion anpassen?

Danke
Garby


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz