Tmemorystream durchsuchen

Für Fragen von Einsteigern und Programmieranfängern...

Re: Tmemorystream durchsuchen

Beitragvon fliegermichl » 21. Jan 2019, 10:02 Re: Tmemorystream durchsuchen

@warf
Toller Algorithmus!
Wäre die Wikipedia Seite so formuliert wie Deine Beschreibung, hätte ich sie auch verstanden. Ich weiss nicht, wieso die Schreiber bei Wikipedia ihre Artikel immer so formulieren, daß sie keine Sau (also ich zumindest) versteht.
fliegermichl
Lazarusforum e. V.
 
Beiträge: 352
Registriert: 9. Jun 2011, 09:42

Beitragvon malabarista » 21. Jan 2019, 10:53 Re: Tmemorystream durchsuchen

Da gibt es leider noch einen Compiler-Fehler, den ich nicht verstehe:

>> if pattern.chars = buff[state] then

Error: Wrong number of parameters specified for call to "GetChar"
Error :Found declaration : GetChar(longint):Char
malabarista
 
Beiträge: 318
Registriert: 11. Jun 2016, 12:16
Wohnort: Konstanz
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0 | 
CPU-Target: 64Bit
Nach oben

Beitragvon braunbär » 21. Jan 2019, 12:31 Re: Tmemorystream durchsuchen

Pattern ist vom Datentyp string - was pattern.chars bedeuten soll, ist mir völig unklar.
Ich weiss zwar, dass man mittlerweile einige String-Funtionen in OOP-Syntax schreiben kann, also statt length(patterm) pattern.length, aber mit pattern.chars kann ich nichts anfangen.
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 18:21

Beitragvon theo » 21. Jan 2019, 12:51 Re: Tmemorystream durchsuchen

https://www.freepascal.org/docs-html/rt ... elper.html

Der Code von Warf ist wahrscheinlich zum selber fertigtüfteln gedacht. ;-)
Bei mir funzt es mal so mit (Nur kurz etwas weiter gehackt).

Code: Alles auswählen
function findInStream(Str: TSTream; pattern: string): integer;
var
  State: integer;
 
  function searchMem(buff: PChar; buffSize: integer): integer;
  begin
    for Result := 0 to buffSize - 1 do
    begin
      if pattern.chars[state] = buff[Result] then
        Inc(state)
      else
        state := 0;
      if State = pattern.length then
      begin
        break;
      end;
    end;
  end;
 
var
  buff: array[0..1023] of char;
  len: integer;
begin
  Str.Position := 0;
  State := 0;
  Result := 0;
  if (Str is TMemoryStream) then
  begin
    with TMemoryStream(Str) do
      Result := searchMem(Memory, Size);
    if State = pattern.length then
    begin
      Dec(Result, pattern.length - 2);
      exit;
    end;
    Result := -1;
  end
  else
    repeat
      len := Str.Read(buff[0], 1024);
      Inc(Result, searchMem(@buff[0], len));
      if State = pattern.length then
      begin
        Dec(Result, pattern.length - 2);
        exit;
      end;
    until len < 1024;
  Result := -1;
end;
theo
 
Beiträge: 8172
Registriert: 11. Sep 2006, 19:01

Beitragvon braunbär » 21. Jan 2019, 19:29 Re: Tmemorystream durchsuchen

Danke für den Link. Zumindest kenne ich fortan "chars".
Was es bringen soll, z.B. pattern.chars{5] an Stelle von pattern[6] zu schreiben, erschließt sich mit zwar nicht, aber irgendwer hat sich sicher etwas dabei gedacht... :D
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 18:21

Beitragvon Warf » 21. Jan 2019, 20:36 Re: Tmemorystream durchsuchen

theo hat geschrieben:Der Code von Warf ist wahrscheinlich zum selber fertigtüfteln gedacht. ;-)
Bei mir funzt es mal so mit (Nur kurz etwas weiter gehackt).

Ja hab den ohne Compiler, etc. ausm kopf geschrieben

braunbär hat geschrieben:Danke für den Link. Zumindest kenne ich fortan "chars".
Was es bringen soll, z.B. pattern.chars{5] an Stelle von pattern[6] zu schreiben, erschließt sich mit zwar nicht, aber irgendwer hat sich sicher etwas dabei gedacht... :D


Ganz einfach, die TStringHelper Funktionen sind alle 0 Basiert, während die normalen funktionen (pos, strutils funktionen, etc.) alle 1 basiert sind. Aber ich arbeite in dem Beispiel mit einer Array-Pointer (also einem Pointer den ich als Dyn Array verwende), und der ist 0 basiert. Bevor ich also irgendwo fehler drin hab weil ich irgendwo ein +1 oder -1 vergessen hab, nehm ich lieber die Helper Funktionen und alles funktioniert gleich.
Was man verwenden will kann man aber selbst entscheiden, man sollte nur bei einem bleiben (also wenn man chars verwendet dann auch str.IndexOf statt pos, etc.), und persönlich (also auch wenn es sich nicht wie in dem beispiel expliziet anbietet) bevorzuge ich den StringHelper, u.a. da bei Str. + Strg+Leer mir die Lazarus vervollständigung alle Möglichen Funktionen anzeigt, ist aber nur eine persönliche präferenz. Kann jeder machen wie er Lustig ist.
Warf
 
Beiträge: 1161
Registriert: 23. Sep 2014, 17:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

• Themenende •
Vorherige

Zurück zu Einsteigerfragen



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste

porpoises-institution
accuracy-worried