AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler in einer while Schleife

Ein Thema von moperswings · begonnen am 2. Mai 2007 · letzter Beitrag vom 4. Mai 2007
Antwort Antwort
Seite 1 von 2  1 2      
moperswings

Registriert seit: 27. Mai 2004
Ort: Bad Sooden-Allendorf
240 Beiträge
 
Delphi 6 Professional
 
#1

Fehler in einer while Schleife

  Alt 2. Mai 2007, 15:53
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;
  Mit Zitat antworten Zitat
BenjaminH

Registriert seit: 14. Okt 2004
Ort: Freiburg im Breisgau
713 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Fehler in einer while Schleife

  Alt 2. Mai 2007, 15:56
Mit Delphi-Referenz durchsuchenPosEx kannst du ab einer bestimmten Stelle suchen.
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.
Benjamin
  Mit Zitat antworten Zitat
stifflersmom

Registriert seit: 8. Dez 2005
Ort: 24994 Holt
379 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

Re: Fehler in einer while Schleife

  Alt 2. Mai 2007, 16:05
Zitat von moperswings:
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;
'ne StringList hat kein EOF also, wieso willst Du das (mit while) nutzen?
Du solltest einfach so Deine StringLsit durchgehen:
Delphi-Quellcode:
For I:= 0 to Inhalt.Count -1 do
...
Moin
  Mit Zitat antworten Zitat
BenjaminH

Registriert seit: 14. Okt 2004
Ort: Freiburg im Breisgau
713 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Fehler in einer while Schleife

  Alt 2. Mai 2007, 16:16
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;
Benjamin
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Fehler in einer while Schleife

  Alt 2. Mai 2007, 16:17
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;
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Fehler in einer while Schleife

  Alt 2. Mai 2007, 16:59
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.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
moperswings

Registriert seit: 27. Mai 2004
Ort: Bad Sooden-Allendorf
240 Beiträge
 
Delphi 6 Professional
 
#7

Re: Fehler in einer while Schleife

  Alt 4. Mai 2007, 09:03
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;
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Fehler in einer while Schleife

  Alt 4. Mai 2007, 10:15
das hier kann doch vereinfacht werden
Delphi-Quellcode:
while pos(s[length(s)], '/>') = 0 do
        delete(s, length(s), 1);
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.
Delphi-Quellcode:
var
  lPos: Integer;
begin
[...]
lPos := Length(s);
while pos(s[lPos], '/>') = 0 do
  dec(lPos);
s := copy(s, 1, lPos);
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:
Delphi-Quellcode:
while (length(s) > 0) and (pos(s[length(s)], '/>') = 0) do
        delete(s, length(s), 1);
bzw.
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:
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;
durch
s := s + Memo1.Lines.Strings[i][p] wird die Länge von s immer wieder geändert. Anfangs hat s eine Länge von 0.
- 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:
length(Memo1.Lines.Strings[i]) - pos(bild, Memo1.Lines.Strings[i]) + 1 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.


nächster Punkt:
Delphi-Quellcode:
if pos(bild, Memo1.Lines.Strings[i]) > 0 then
begin
  s := '';
  for p := pos(bild, Memo1.Lines.Strings[i]) to [...]
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.


Zitat:
Ich hätte es vor allem noch gerne in einer Stringliste, damit ich mir das Memo sparen kann
dann lege doch einfach eine Stringliste an ( StringListInstanz := TStringList.Create() )


Hab den Quelltext von dir allerdings nur überflogen. Ich hoffe also ich hab nicht irgendwelchen Quelltext falsch verstanden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
moperswings

Registriert seit: 27. Mai 2004
Ort: Bad Sooden-Allendorf
240 Beiträge
 
Delphi 6 Professional
 
#9

Re: Fehler in einer while Schleife

  Alt 4. Mai 2007, 10:51
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!
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Fehler in einer while Schleife

  Alt 4. Mai 2007, 10:55
Zitat von moperswings:
Mit der Stringliste wäre ich ja wieder am Anfang meines Problems, dass ich da keinen Schleifen-Durchlauf hinbekomme
du musst doch einfach nur "Memo1.Lines." durch "deineStringliste." ersetzen.
Delphi-Quellcode:
deineStringListe := TStringList.Create();
try
//dein bisheriger Quelltext mit "deineStringListe." anstelle von "Memo1.Lines."
finally
  deineStringListe.Free;
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz