wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

wie kann ich in einem buffer (TFileStream) einen string suchen und finden?


hi leute, jetzt kommt wahrscheinlich eine blöde frage an euch....

ich habe ein grosses problem....
ich lese einen kompletten prozess aus und speichere nacheinander alle regionen in einem buffer
(buf : array of char) vom typ (FileStream: TFileStream)
das alles läuft wunderbar, ABER
wie kann ich einen string, z.b 'inge' in diesem blöden buffer finden?????

trotz meiner suche im i-net habe ich leider nichts gefunden was ich verstehen konnte :(
ihr seid jetzt meine einzige hoffnung....
das problem liegt mit sicherheit zwischen meinen ohren und an meinem hohen alter von 69 jahren :(
ich steige da einfach nicht mehr durch :( und bitte euch um hilfe.
vielen lieben dank im voraus.

mfg
lui

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von aro »

Hallo,

Du nimmst am besten eine for next -Schleife (Next = Dateilänge).

dann testest Du ob das erste Zeichen deines Suchstrings mit der aktuellen Position im Steam übereinstimmt.
Wenn ja dann aktuellen Position +1 im Steam mit dem zweiten Zeichen deines Suchstrings und so weiter.

Wenn alle Zeichen perfekt stimmen dann break.

Ansonsten die For next - Schleife weiter durchgehen bis zum bitteren Ende.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von fliegermichl »

Wir hatten das Thema schonmal hier und weil mir der Algorithmus so gut gefiel, hab ich mir das notiert.

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 = buff[state] then
      Inc(state)
    else
      state := 0;
    if State = pattern.length then break;
  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 Result := -1;
    exit;
  end;
  repeat
    len := Str.Read(buff[0], 1024);
    Inc(Result, searchMem(@buff[0], len));
    if State = pattern.length then
    begin
      Dec(Result, pattern.length);
      exit;
    end;
  until len < 1024;
  Result := -1;
end;
Trag diesen Code in dein Programm ein und dann kannst du mittels

Code: Alles auswählen

var i : integer;
begin
 i := FindInStream(MyFilestream, 'inge');
 if (i<0) then
  Showmessage('Konnte inge nicht finden')
 else
  Showmessage(Format('Inge befindet sich an Position %d im Stream', [i]));
end;
LG Michael

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

erst mal vielen dank für eure schnelle antwort

das habe ich schon probiert mit

FileStream.Read(buf[B1],1); B1 ist mein schleifenzähler

aber damit finde ich überhaupt nix :( zudem ist diese suche viel zu langsam bei diesen datenmengen.

kann man nicht auch mit pos wie in einem string suchen?, wäre doch viel schneller und müsste doch irgendwie gehen, nur weis ich nicht wie...

ups, hab eben den code gesehen, danke aro und michael, das werde ich testen,

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

hi leute, hoffe ich nerve euch nicht zu sehr. :roll:

leider bekomme ich bei dem oberen code 2 fehlermeldungen in der function searchMem ab zeile

if pattern.chars = buff[state] then // Error: Wrong number of parameters specified for call to "GetChar"
// syshelp.inc(154,24) Error: Found declaration: GetChar(Int64):Char;

keine ahnung was das wieder bedeutet, ich arbeite mit lazarus-ide v2.0.12 r64642
naja, wäre doch zu einfach gewesen, schade :(

vieleicht gibt es doch noch eine schelle lösung mittels pos in einem string zu suchen,

hmmm... kann man den TFileStream nicht in einen langen string einlesen und mit pos darin suchen? :?:
klar, das würde den doppelten speicherplatz belegen, das wäre mir aber echt 'wurscht' :)
probiert habe ich diesen weg schon, aber klappt leider auch nicht :(

mfg
lui

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von wp_xyz »

Rentner Lui hat geschrieben:
Di 27. Apr 2021, 14:41
ich lese einen kompletten prozess aus und speichere nacheinander alle regionen in einem buffer
(buf : array of char) vom typ (FileStream: TFileStream)
Ich verstehe die Fragestellung schon gar nicht: du liest irgendwas ein und speicherst es in einem Puffer, der ein Array of char ist, aber auch vom Typ TFileStream. Also was denn nun? Stehen die Daten nun in einem Array of char oder noch in einem TFileStream?

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

also ich denke die stehen im puffer....

ReadProcessMemory(hProcess, memInfo.BaseAddress, Addr(buf), memInfo.RegionSize, cbRead) then
FileStream.Write(buf[0], cbRead);

leider finde ich nix im filestream, hmmm, sollte ich im buffer suchen?

entschuldige bitte meine unkentnis, ich schau mal im buffer nach.

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

wenn ich meinen buffer auslese und zwar so:
var
buf : array of char;
B1:int64;
BB:char;

danach werden die ram-wete eingelesen
--------------------------------------
und damit wollte ich suchen

for B1:=0 to length(buf) do begin
BB:=buf[B1];
Showmessage ('GELESEN -->'+BB+'<--');
end;


bekomme ich tausende mal die meldung GELESEN -->

aber es sollte doch GELESEN --> irgend ein charakter <----- rauskommen
nur das irgend ein charakter <-- fehlt immer

anscheinend wird da jede menge vom buffer angezeigt. aber ich übergebe dem charwert BB doch nur 1 zeichen?

wahrscheinlich bin ich nur zu blöd um das ganze zu verstehen.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von wp_xyz »

Nach diesem Code stehen die Zeichen im Puffer, und du könntest mit StrPos suchen, wie in diesem Beispiel (Das klassiche pos() ginge auch, nur muss dazu dein Puffer ein String sein):

Code: Alles auswählen

program Project1;

uses
  SysUtils;
const
  N = 1000;
var
  buf: array[0..N-1] of char;
  P: PChar;

  function SucheInBuffer(Sequenz: String): Integer;
  var
    P: PChar;
  begin
    P := StrPos(PChar(buf), PChar(Sequenz));
    Result := P - PChar(buf);
  end;

begin
  FillChar(buf, N, ' ');
  buf[20] := 'H';
  buf[21] := 'a';
  buf[22] := 'l';
  buf[23] := 'l';
  buf[24] := 'o';

  WriteLn('Suchstring beginnt bei index: ', SucheInBuffer('ll'));

  ReadLn;
end.
Zuletzt geändert von wp_xyz am Di 27. Apr 2021, 19:22, insgesamt 1-mal geändert.

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

oh, danke, vielen dank,

das werde ich bei mir testen.

zur zeit schwirren meine gehirnwindungen durch die gegend.
aber in dieser corona-zeit haben selbst die rentner zeit :)

irgendwo mache ich einen fehler, aber mit eurer hilfe werde ich den schon noch finden.
vor ca 20 jahren hatte ich mein altes delphi zum letzten mal benutzt.........
ist mir aber zu teuer, deshalb lazarus :)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von wp_xyz »

Rentner Lui hat geschrieben:
Di 27. Apr 2021, 18:57
aber ich übergebe dem charwert BB doch nur 1 zeichen?
Schon. Aber wenn das BB ein Null-Char ist (#0)? Denn ShowMessage ist eine Prozedur des GUI, und die Strings werden nicht von Lazarus ausgegeben, sondern vom Betriebssystem - und dort gelten die Regeln von C, wonach ein String mit einer #0 endet.

Arbeitest du mit Windows? Dann könntest du testhalber in den Projekt-Optionen das Häkchen vor "Konfiguration und Ziele" > "Win32-GUI-Anwendung" wegmachen, so dass du auch mit den alten WriteLn-Anweisungen in ein automatisch erstelltes Konsolenfenster schreiben kannst. Und WriteLn ist Pascal, sollte also nach der #0 weiterschreiben.

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

ja ich nutze win7 64 bit

oh nein, ich hasse C ! das kann doch kein mensch lesen!
jetzt wird's schwer, aber ich schau mal, ich glaube in dem ziel habe ich win 64 eingetragen.

aber für heute nacht habe ich genügend zum testen, mit euren ganzen code die ihr mir gegeben habt
kopieren und einfügen...... das kann ich zumindest noch :)

spätestens morgen früh werde ich euch wieder nerven.

nochmals vielen lieben dank für eure hilfe
mfg
lui

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von aro »

Hallo,
da hilft nur systematische Fehlersuche.

Folgenden Vorschlag : Egal wie dein Quelltext auch immer ausfallen wird.
for B1:=0 to length(buf) do begin
BB:=buf[B1];
Showmessage ('GELESEN -->'+BB+'<--');
end;
Als erstes die Zeile "Showmessage" auskommentieren - die stört nur.

dann in die Zeile "BB:=buf[B1];" einen Breakpoint setzen.

Dann das Programm starten - es wird in der Zeile "BB:=buf[B1];" stehen bleiben.

jedes mal wenn du F8 oder F9 drückst wird das Programm um ein Zeichen weiter arbeiten.

Wenn Du jetzt mit der Maus im Quelltext über einem Variablenname befindest, wird der Inhalt oder Wert der Variablen angezeigt.

Da kannst Du als erstes Überprüfen ob Dein Stream überhaupt den Text enthält, den Du erwartest.
Dann ob bb immer ein Zeichen weiter zählt.

Eben Schritt für Schritt das Programm verfolgen und bei jedem Schritt nachschauen ob Du das Ergebnis erreichst, was gewollt war.

Damit findet man sehr viele Fehler.

Außerdem ist es für die Bearbeitungszeit völlig belanglos ob Du StrPos, pos() oder Deine eigene Schleife verwendest !

Fakt ist, das Du jedes Zeichen des Streams mit der Suchzeichenkette vergleichen musst. Fertige Funktionen sind einfacher zu verwenden - eigene Funktionen sind manchmal effizienter, das man sie auf eigene Bedingungen optimieren kann.

Rentner Lui
Beiträge: 17
Registriert: Di 27. Apr 2021, 14:34

Re: wie kann ich in einem buffer (TFileStream) einen string suchen und finden?

Beitrag von Rentner Lui »

vielen dank für deinen rat, das wusste ich alles noch nicht und wird mir mit sicherheit weiterhelfen.
hab's gleich kopiert und an sicherer stelle gespeichert.

jetzt zum thema:
ich bin zur erkenntnis gekommen, das ich sehr viel verlernt habe, vieles hat sich auch geändert delphi->lazarus, 16,32,64 bit usw......
deshalb werde ich mit diesem projekt nicht weitermachen UND von ganz vorne anfangen.
hoffentlich vergeht mir dabei nicht die lust am programmieren. für meine gehirnwindungen wäre es sicher nicht schlecht.

für eure hilfe möchte ich mich hier nochmals bei euch recht herzlich bedanken :)
falls ich wieder fragen habe (wird nicht lange dauern) werde ich euch hier im forum um hilfe ersuchen und etwas nerven :roll:

mfg
lui

Antworten