Einzelnen Beitrag anzeigen

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