Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - MemoryStream mit Pointern durchforsten
sahib - Di 31.05.05 02:08
Titel: MemoryStream mit Pointern durchforsten
Hi.
Ich habe eine Textdatei in einen TMemoryStream eingelesen und durchforste den Speicherbereich nun nach mir wichtigen Daten. Ich hatte ähnliches schon einmal mit einer TStringList gemacht. Aber das war sehr speicherintensiv und auch nicht sonderlich schnell.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var Stream: TMemoryStream; p, q: PChar; begin p := Stream.Memory;
q := p + 100; end; |
Jetzt habe ich aber das Problem, den Bereich zwischen p und q in einen String oder PChar (vielleicht besser?) zu bekommen. Wie kann ich das anstellen? Bei mir kommet immer nur das CPU-Fenster :( Ich könnte Zählvariablen mitlaufen lassen und dann mit Move arbeiten. Aber ich müsste doch mit den Pointern selber rechnen können, oder?
Christian
Delete - Di 31.05.05 04:53
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Button1Click(Sender: TObject); var ms: TMemoryStream; p: PChar; begin ms := TMemoryStream.Create; try ms.LoadFromFile('d:\Dokumente\Träume vom 2004-02-25.txt'); p := ms.Memory; while p^ <> #0 do begin ShowMessage(p^); Inc(p); end; finally FreeAndNil(ms); end; end; |
Gibt dir jedes Zeichen einzeln in dem Dialog aus. Nachteil: Du kannst keine AnsiStrings verwenden, da in AnsiStrings auch das #0 Zeichen vorkommen kann, bei PChar's ist es das Stringende-Zeichen.
Erweiterung:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| procedure TForm1.Button1Click(Sender: TObject); var ms: TMemoryStream; p, q, r: PChar; i: Integer; s: string; begin i := 0; ms := TMemoryStream.Create; try ms.LoadFromFile('d:\Dokumente\Träume vom 2004-02-25.txt'); p := ms.Memory; q := p; r := p; while p^ <> #0 do begin if p^ = 'd' then begin Inc(q, 3); Dec(r, 1); if (q^ = #32) and (r^ = #32) then begin SetString(s, p, q - r - 1); if (s = 'der') or (s = 'das') or (s = 'die') then begin ListBox1.Items.Add(s); Inc(i); end; end; Dec(q, 3); Inc(r); end; Inc(p); Inc(q); Inc(r); end; finally FreeAndNil(ms); end; ShowMessage(IntToStr(i)); end; |
Zählt dir alle bestimmten Artikel (der, die, das) in einem Text.
Ich weiß nicht, was du vor hast, aber es wäre zu überlegen, ob du dich nicht mal über Reguläreausdrücke schlau machst.
sahib - Di 31.05.05 09:48
Danke Michael.
Die Funktion SetString fehlte mir, da muss ich mal ein wenig nachlesen. Ich hatte erst mit Move gearbeitet und dabei falsche Daten erhalten. An das schlau machen bezüglich regulärer Ausdrücke dachte ich auch schon, aber das ist ja auch so eine Wissenschaft für sich. Erste Gehversuche meinerseits waren beschämend. Dass sie zweifelsohne mächtiger sind, als selbstgeschriebene Routinen zum auffinden von Texten, ist klar. Wie sieht das aber mit der Geschwindigkeit aus? Das Übersetzen des Ausdrucks nimmt ein wenig Zeit in Anspruch, das sollte aber kein Problem sein, weil der für die Datei gleich bliebe und so nicht in der innersten Schleife verweilte. Die TRegExpr von Andrey V. Sorokin macht einen guten Eindruck.
Christian
deccer - Di 31.05.05 09:55
Move funktioniert ähnlich wie SetString :)
Quelltext
1:
| Move(Pointer(sZielString)^, pDeinPointer^, iAnzahlAnBytesOderDieLaengeDieDerStringHabenSoll); |
oder
Quelltext
1: 2:
| SetLength(sZielString, iAnzahlAnBytesOderDieLaengeDieDerStringHabenSoll); Move(sZielString[1], pDeinPointer^, iAnzahlAnBytesOderDieLaengeDieDerStringHabenSoll); |
sahib - Di 31.05.05 10:33
Hallo deccer.
Ersteres Code-Schnipsel sieht ja lecker aus - muss ich mal testen. Ich dachte, dass ich immer wie im zweiten Beispiel vorgehen müsste, nämlich der Initialisierung der Stringlänge. Aber wenn das wie im ersten klappt... ;)
*edit* Ok, reguläre Ausdrücke mit der von mir erwähnten Unit sind viel zu langsam.
Christian
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!