![]() |
Fehler in einer while Schleife
Hallo,
ich möchte eine *.html-Datei nach Bildern durchsuchen und die gefundenen Bilder sollen in einer Listbox angezeigt werden. Ich weiss aber nicht, wie ich mit einer while-Schleife eine TStringliste durchlaufen lasse. Ohne while wird mir nur das erste Bild angezeigt. Hoffe, Ihr könnt mir helfen! Viele Grüsse, moperswings
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var dateiname: string; inhalt: TStringlist; pic_start: string; i: integer; temp: String; begin pic_start := '<img src'; dateiname := 'd:\image14\daten.html'; Memo1.Lines.LoadFromFile(dateiname); inhalt := TStringlist.Create; inhalt.LoadFromFile(dateiname); while not EOF({inhalt läuft nicht}) do begin for i := 0 to inhalt.Count - 1 do if pos(pic_start, inhalt[i]) <> 0 then begin temp := inhalt[i]; Listbox1.Items.Add(temp); inhalt.free; exit; end; end; end; |
Re: Fehler in einer while Schleife
Mit
![]() Das heißt du suchst erst nach dem ersten vorkommen und dann nimmst du den Wert, den PosEx zurückliefert um ab da weiter zu suchen. |
Re: Fehler in einer while Schleife
Zitat:
Du solltest einfach so Deine StringLsit durchgehen:
Delphi-Quellcode:
Moin
For I:= 0 to Inhalt.Count -1 do
... |
Re: Fehler in einer while Schleife
Ich würde das so machen, ich denke das ist das einfachste.
Delphi-Quellcode:
p:Integer;
pic_start := '<img src="'; p:=pos(pic_start, Memo1.Text); [etc] while p<>0 do Begin Listbox1.Items.Add(substr(Memo1.Text,Copy(Memo1.Text,p+Length(pic_start),PosEx('"',Memo1.Text,p+Length(pic_start))); p:=posex(pic_start, Memo1.Text,p); End; |
Re: Fehler in einer while Schleife
Du solltest die StringList auch nicht versuchen, in einer Schleife freizugeben, selbst wenn es EOF gäbe. Mach sowas generell so, damit die StringList auch sicher wieder freigegeben wird:
Delphi-Quellcode:
inhalt := TStringlist.Create;
try while (...) begin ... end; finally FreeAndNil(inhalt); end; |
Re: Fehler in einer while Schleife
Moin Benjamin,
Du solltest aber niemals TStrings.Text (z.B. bei Memo) in einer Schleife verwenden, sondern immer eine String-Variable für so etwas nehmen, da die Eigenschaft Text bei jedem Lesezugriff aus den Zeilen zusammengesetzt wird (gilt analog auch für das Schreiben). Immer Text zu verwenden ist eine der "besten" Performancebremsen. |
Re: Fehler in einer while Schleife
Hallo,
hier ist meine - nach langem Leiden - vorläufige Lösung: Wer eine Idee hat, wie man das optimieren oder wie es ganz anders laufen könnte, dann her damit! Ich hätte es vor allem noch gerne in einer Stringliste, damit ich mir das Memo sparen kann, was ich eigentlich für mich nur zur Kontrolle eingebaut habe, um zu sehen, ob auch alle Bilder gefunden werden. Ich würd mich freuen! Ich hoffe auch, hiermit eine allgemeine Lösung zu liefern, wie man einen Textteil filtern kann und so anderen auch mal helfen könnte! Viele Grüsse, moperswings
Delphi-Quellcode:
procedure TForm1.Button14Click(Sender: TObject);
var i, p: integer; s: string; bild: string; dateiname: string; begin dateiname := 'd:\image14\daten.html'; Memo1.Lines.LoadFromFile(dateiname); bild := '<img'; for i := 0 to Memo1.Lines.Count - 1 do begin if pos(bild, Memo1.Lines.Strings[i]) > 0 then begin s := ''; for p := pos(bild, Memo1.Lines.Strings[i]) to length(Memo1.Lines.Strings[i]) do if memo1.Lines.Strings[i][p] <> s then s := s + Memo1.Lines.Strings[i][p] else break; while pos(s[length(s)], '/>') = 0 do delete(s, length(s), 1); ListBox1.Items.Add(s); end; end; end; |
Re: Fehler in einer while Schleife
das hier kann doch vereinfacht werden
Delphi-Quellcode:
anstelle bei jedem durchlauf das ganze zu kürzen kannst du auch einfach eine Varialbe nehmen in der du dir die Position merkst und dann am Ende einmal nur die ganzen zeischen löschst.
while pos(s[length(s)], '/>') = 0 do
delete(s, length(s), 1);
Delphi-Quellcode:
Zudem solltest du dort eine Prüfung einbauen damit nicht auf Index 0 des Strings zugegriffen wird und auch keine endlosschleife draus wird falls keines der zeichen vorkommt:
var
lPos: Integer; begin [...] lPos := Length(s); while pos(s[lPos], '/>') = 0 do dec(lPos); s := copy(s, 1, lPos);
Delphi-Quellcode:
bzw.
while (length(s) > 0) and (pos(s[length(s)], '/>') = 0) do
delete(s, length(s), 1);
Delphi-Quellcode:
var
lPos: Integer; begin [...] lPos := Length(s); while (lPos > 0) and (pos(s[lPos], '/>') = 0) do dec(lPos); s := copy(s, 1, lPos); nächster Punkt: Anstelle jedes mal "memo1.Lines.Strings[i]" zu verwenden solltest du das ganze auf eine zwischenvariable zuweisen denn "memo1.Lines.Strings[i]" ruft intern jedesmal SendMessage auf um den Inhalt der Zeile abzufragen, kopiert dann den Inhalt in einen String und liefert dir diesen zurück. Wenn du also eine Zwischenvariable nutzt wird nur einmal das ganze in einen Puffer geschrieben der dir zurück gegeben wird und auf diesem kannst du dann viel schneller arbeiten. nächster Kritikpunkt ist folgender Block (mal ordentlich formatiert)
Delphi-Quellcode:
durch
for p := pos(bild, Memo1.Lines.Strings[i]) to length(Memo1.Lines.Strings[i]) do
if memo1.Lines.Strings[i][p] <> s then s := s + Memo1.Lines.Strings[i][p] else break;
Delphi-Quellcode:
wird die Länge von s immer wieder geändert. Anfangs hat s eine Länge von 0.
s := s + Memo1.Lines.Strings[i][p]
- Dann eine Länge von 1 -> Speicher für 1 Zeichen wird reserviert - Dann eine Länge von 2 -> Speicher für 2 Zeichen wird reservert, das 1 Zeichen vom Schritt davor wird in den neuen Speicher kopiert, das neue Zeichen wird an die letzte Stelle im neuen Speicher geschrieben, Speicher vom Schritt davor wird frei gegeben - Dann eine Länge von 3 -> Speicher für 3 Zeichen wird reservert, die 2 Zeichen vom Schritt davor werden in den neuen Speicher kopiert, das neue Zeichen wird an die letzte Stelle im neuen Speicher geschrieben, Speicher vom Schritt davor wird frei gegeben [...] es wird also immer wieder neuer speicher reserviert und der Inhalt wird umher kopiert weil der alte reservierte Speicher für den String nicht ausreicht. Du weißt ja aber vorher das dein String eine maximale Länge von:
Delphi-Quellcode:
zeichen haben kann. Setzte also mit SetLength die Variable s gleich auf diese maximale größe und zähle in einer variablen mit wieviel Zeichen du bisher rein geschrieben hast. Nach der Schleife setzt du dann mit SetLength die Größe von s auf die tatsächlich benötigte Größe. Und schon fällt das ständige umherkopieren und neu reservieren von speicher weg.
length(Memo1.Lines.Strings[i]) - pos(bild, Memo1.Lines.Strings[i]) + 1
nächster Punkt:
Delphi-Quellcode:
du rufst zweimal hintereinander pos auf mit den gleichen Parametern auf. Es wird also 2 mal nach dem ersten vorkommen gesucht. Sinnvoller wäre es hier doch das ergebnis des ersten Aufrufes in einer Variable zu speichern.
if pos(bild, Memo1.Lines.Strings[i]) > 0 then
begin s := ''; for p := pos(bild, Memo1.Lines.Strings[i]) to [...] Zitat:
Hab den Quelltext von dir allerdings nur überflogen. Ich hoffe also ich hab nicht irgendwelchen Quelltext falsch verstanden. |
Re: Fehler in einer while Schleife
Vielen Dank Grosser Meister!
Um Dein Posting durchzuarbeiten brauche ich noch Zeit! Mit der Stringliste wäre ich ja wieder am Anfang meines Problems, dass ich da keinen Schleifen-Durchlauf hinbekomme :-( Vielen Dank erstmal, ich schreibe zurück, wenn ich Deinen Text durchgearbeitet und verstanden (ich bemühe mich) habe! |
Re: Fehler in einer while Schleife
Zitat:
Delphi-Quellcode:
deineStringListe := TStringList.Create();
try //dein bisheriger Quelltext mit "deineStringListe." anstelle von "Memo1.Lines." finally deineStringListe.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:28 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