Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Stringende wieder hinzufügen (https://www.delphipraxis.net/118897-stringende-wieder-hinzufuegen.html)

TheMiller 17. Aug 2008 15:22


Stringende wieder hinzufügen
 
Hallo,

da diese Frage spezieller ist, eröffne ich einen neuen Thread, der aber eigentlich zu dem hier (Stream wie Editor einlesen)

Also, ich habe in dem oben genannten Thread eine Funktion gepostet bekommen, mit der ich das Stringende-Zeichen #0 entfernen kann. Nun zeigt mir das Memo alles toll an. Damit ich die Datei wieder speichern kann, habe ich das #0 durch ?) ersetzt. Nun möchte ich das ?)-Zeichen wieder in #0 mit StrReplaceBin umwandeln. Doch da fügt er nur das erste Zeichen ein, erkennt natürlich wieder ein Stringende und hört somit auf. Somit habe ich nur die ersten 4 Bytes (?) glaube ich.

Die Datei kann also nicht mehr gespeichert werden. Ich denke, dass StrReplaceBin müsste am Ende der Datei anfangen zu ersetzen und sich vorarbeiten, damit sie nicht vorzeitig abbricht. Doch die Funktion ist in ASM und davon habe ich noch weniger Ahnung.

Bitte um Hilfe!

Danke

Apollonius 17. Aug 2008 15:26

Re: Stringende wieder hinzufügen
 
Du kannst doch einfach den String mit einer for-Schleife durchlaufen und jedes Ersatzzeichen durch ein #0 ersetzen.

TheMiller 17. Aug 2008 15:29

Re: Stringende wieder hinzufügen
 
Das darf doch dann aber kein String-#0 sein. Es muss ja ein Binärwert sein... Sonst habe ich ja #0 da stehen und nicht ein tatsächliches Stringende. Oder?

omata 17. Aug 2008 15:32

Re: Stringende wieder hinzufügen
 
Und welches Ersatzzeichen soll man da nehmen? Vielleicht ist ja z.B. das Fragezeichen vorher auch ein Fragezeichen gewesen und nicht #0 :zwinker:

TheMiller 17. Aug 2008 15:36

Re: Stringende wieder hinzufügen
 
Ich will ja kein Ersatzzeichen, ich mag ja nur mein Ersatzzeichen wieder in ein Binär-#0-Zeichen umwandeln.

Apollonius 17. Aug 2008 15:38

Re: Stringende wieder hinzufügen
 
#0 ist das Zeichen mit dem Binärwert 0, wird also bei PChars als Stringende interpretiert. Der Trick liegt darin, dass bei Strings im Gegensatz zu PChars noch eine zusätzliche Längenangabe vorliegt, auf die mit Length() zugegriffen wird. Damit umgehst du das Problem des vorzeitigen Abbrechens.

TheMiller 17. Aug 2008 15:45

Re: Stringende wieder hinzufügen
 
Hm.. das hab ich nicht ganz verstanden.

Zuerst wandel ich den Kram folgendermaßen um, um ihn im Memo anzuzeigen:

Delphi-Quellcode:
//String, Suchen_nach, Ersetzen-durch
StrReplaceBin(s, #0, '&%');
Nun kann ich es im Memo alles ansehen. Um zu speichern, wollte ich wieder zurückwandeln:

Delphi-Quellcode:
StrReplaceBin(s, '&%', #0);
Da ersetzt er nur bis zum ersten Vorkommen, danach ist für ihn der String zu Ende.

Ich habe nicht ganz verstanden, wie dieser "Trick" funktionieren soll, den du geschrieben hast - bzw wie ich ihn umsetze.

Apollonius 17. Aug 2008 15:55

Re: Stringende wieder hinzufügen
 
Hm, mit einem Ersetzungsstring, der größer als ein Byte ist, wird das etwas schwieriger. Allerdings nicht unmöglich:
Delphi-Quellcode:
procedure Fix0Bytes(var Str: String);
var i, j: Integer;
begin
  i := 1;
  j := 1;
  while i < Length(Str) do
    if (Str[i] = '&') and (Str[i+1] = '%') then
    begin
      Str[j] := #0;
      Inc(i, 2);
      Inc(j);
    end
    else
    begin
      Str[j] := Str[i];
      Inc(i);
      Inc(j);
    end;
  SetLength(Str, j);
end;
Ich habe es nicht getestet, aber zumindest mit Ansistrings müsste es so gehen.

TheMiller 17. Aug 2008 15:58

Re: Stringende wieder hinzufügen
 
Hey...

hab mal Copy&Paste gemacht, das Ergebnis ist leider das gleiche. Vielleicht müssen wir die Funktion so umschreiben, dass sie am Dateiende beginnt, die Strings zu ersetzen und sich zum Beginn der Datei vorarbeitet. Das könnte doch gehen, oder?

Apollonius 17. Aug 2008 15:59

Re: Stringende wieder hinzufügen
 
Wie speicherst du denn den String?

TheMiller 17. Aug 2008 16:00

Re: Stringende wieder hinzufügen
 
Ups.... durch TStringList - das könnte natürlich einiges Erklären...

Apollonius 17. Aug 2008 16:01

Re: Stringende wieder hinzufügen
 
Wenn du einen TFileStream verwendest, sollte es funktionieren.

TheMiller 17. Aug 2008 16:12

Re: Stringende wieder hinzufügen
 
Ich habe einen MemoryStream verwendet und dann aus Platte geschrieben... Doch so ganz entfert er die "&%"-Zeichen nicht. Hier mal die Originaldatei und die Datei aus dem Stream:

Code:
ÿØÿà JFIF  H H ÿá‚Exif II*    
     †       ”              š       ¢   (       1    ª   2    Æ          i‡    Ü   T
Code:
ÿØÿà %JFI &%  %  %H&%&%ÿá  Exi &  I *&% &  &  % &  %   %†& &     %& &  ”   %&%       %&% &  &  &% &  &  %&% %   &  %&% %   &  ( %   &  & %&%1&%&%&% %ª&%& &%2 & &%& &%  %&%&%&%&%&%&%&%&%&%i‡ %&%&%&%Ü&%&%&%
Hm... hilft das weiter? Sieht seltsam aus...

Apollonius 17. Aug 2008 16:14

Re: Stringende wieder hinzufügen
 
Ich hatte im Else-Zweig eine Zeile vergessen.

grenzgaenger 17. Aug 2008 16:19

Re: Stringende wieder hinzufügen
 
probier das mal:
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils;

function Replace(const aStr: string;
                 const aSearchStr: string;
                 const aReplaceChar: char): string;
var
 l,x: integer;    
 c: PChar;          
begin
 setlength(result, length(aStr));
 c := @aStr[1];
 x := 0;
 for l := 1 to length(aStr) do
 begin
  inc(x);
  if pos(aSearchStr, c) = 1 then
  begin
   result[x] := aReplaceChar;
   inc(c, length(aSearchStr));
  end
  else
  begin
   result[x] := c^;
   inc(c);
  end;
 end;
 setlength(result, x);
end;
 
begin
 writeln(Replace('a&%68&%a4', '&%', #0));
 readln;
end.
in der performance kann man da sicher noch was machen... sollte aber funzzen...

ansonsten, denk an omata das ganze, kann nicht bei einem binärformat vernünftig funktionieren...

hierzu müsstest du schon beim lesen, z.b. in hexcode umwandeln, in hexcode editieren und beim speichern den hex wieder in die binärdarstellung bringen...

aber das wirst schon selbst noch merken ... :drunken:

Christian Seehase 17. Aug 2008 22:43

Re: Stringende wieder hinzufügen
 
Moin DJ-SPM,

warum nimmst Du nicht einfach StringReplace? :gruebel:

Delphi-Quellcode:
sErgebnisMitBinaerenNullen := StringReplace(Memo1.Text,'DeineErsatzzeichen',#00,[rfReplaceAll,rfIgnoreCase]);


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:22 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-2025 by Thomas Breitkreuz