Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - EXIT verlässt Proc nicht??
D. Annies - Mo 08.01.07 15:57
Titel: EXIT verlässt Proc nicht??
Hi, Delpher,
Warum verlässt EXIT oder die Boolesche Variable "raus"/true nicht die Prozedur, bzw. wie wird die Rekursion richtig bei 'Abbruch' verlassen?
Ich habe zur Sicherheit den vollständigen Proc-Code angegeben.
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: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104:
| Procedure TForm1.FindFiles (aPath, aFindMask: String; aWithSub: Boolean; aResult: tStrings); Var FindRec : tSearchRec; existingfilename, pr_filename : string; dname, uvname : string; n, erg : integer; raus : boolean; Begin raus := false; If (aPath = '') or (aFindMask = '') or Not Assigned (aResult) Then Exit; If aPath[Length(aPath)] <> '\' Then aPath := aPath + '\'; meldung := ''; If FindFirst (aPath + aFindMask, faAnyFile - faDirectory, FindRec) = 0 Then Repeat If (FindRec.Name <> '.') and (FindRec.Name <> '..') Then begin if IsfileInUse(aPath + findrec.Name) = true then begin dname := Findrec.Name; if extractfileext(dname) = '.dbf' then schliesse_DBTab(self); end; if IsfileInUse(aPath + findrec.Name) = false then aResult.Add (aPath + FindRec.Name); if FileDateToDateTime(FileAge(apath+FindRec.Name)) < now then begin if (FindRec.Name[1] = '_') or (pos('.~', FindRec.Name) > 0) then begin showmessage(apath + findrec.name + ' wird gelöscht'); DeleteFile(apath + FindRec.name) end else if (pos('.pas', FindRec.Name) > 0) or (pos('.dfm', FindRec.Name) > 0) or (pos('.dcu', FindRec.Name) > 0) or (pos('.exe', FindRec.Name) > 0) or (pos('.dpr', FindRec.Name) > 0) or (pos('.ddp', FindRec.Name) > 0) or (pos('.dof', FindRec.Name) > 0) or (pos('.dsk', FindRec.Name) > 0) then begin end else begin uvname := ''; for n := pos('Buecherei\', apath)+10 to length(apath) do uvname := uvname + apath[n];
ExistingFilename := apath + FindRec.name;
if apath[1] = label38.Caption[1] then begin if label30.Caption[length(label30.Caption)] = '\' then Pr_FileName := label30.caption + uvname + FindRec.name else Pr_FileName := label30.caption + '\' + uvname + FindRec.name end else if apath[1] = label30.Caption[1] then begin if label38.Caption[length(label38.Caption)] = '\' then Pr_FileName := label38.caption + uvname + FindRec.Name else Pr_FileName := label38.caption + '\' + uvname + FindRec.Name; end;
if fileexists(Pr_FileName) then begin if FileDateToDateTime(FileAge(Pr_FileName)) <> FileDateToDateTime(FileAge(existingfilename)) then begin erg := xmessagedlg('Soll ' + pr_filename+ ' '+datetimetostr(filedatetodatetime(FileAge(Pr_Filename))) +#13+ 'durch ' + existingfilename+ ' '+datetimetostr(filedatetodatetime(FileAge(ExistingFileName))) +#13+ ' ersetzt werden?', mtConfirmation, [mbYes, mbno, mbcancel], ['ja', 'nein', 'Abbrechen'], self.font);
case erg of mryes : CopyFile(PChar(ExistingFileName), PChar(Pr_FileName), FALSE); mrcancel : raus := true; end; end; end else begin if not (label30.Caption[length(label30.Caption)] = '\') then label30.Caption := label30.Caption + '\'; erg := xmessagedlg('Soll '+ pr_filename + ' angelegt werden?', mtConfirmation, [mbYes, mbNo, mbcancel], ['ja', 'nein', 'Abbrechen'], self.font); case erg of mryes : begin if not directoryexists(label30.caption+uvname) then forcedirectories(label30.caption+uvname); CopyFile(PChar(ExistingFileName), PChar(Pr_FileName), TRUE); end; mrcancel : raus := true; end; end; end; end else showmessage('???'); end; Until FindNext (FindRec) <> 0; FindClose (FindRec);
If (Not aWithSub) or (raus) Then Exit; If FindFirst (aPath + '*.*', faAnyFile, FindRec) = 0 Then Repeat If (FindRec.Name <> '.') and (FindRec.Name <> '..') Then If Boolean (FindRec.Attr and faDirectory) Then If ((FindRec.Attr and faDirectory) <> 0) then FindFiles (aPath + FindRec.Name, aFindMask, aWithSub, aResult); Until FindNext (FindRec) <> 0; FindClose (FindRec); End; |
Danke für Hilfe, sagt Detlef A.
Coder - Mo 08.01.07 16:06
Probier mal ab Zeile 100
Delphi-Quelltext
1: 2: 3: 4: 5:
| If ((FindRec.Attr and faDirectory) <> 0) then begin FindFiles (aPath + FindRec.Name, aFindMask, aWithSub, aResult); if raus then Exit; end; |
Ist nur geraten.
Edit// War quatsch.
Narses - Mo 08.01.07 16:18
Moin!
Exit beendet nur die aktuelle Instanz einer Prozedur, nicht den gesamten rekursiven Aufruf. :? Ich gebe allerdings zu, habe den Code max. "überflogen"... :|
cu
Narses
Chatfix - Mo 08.01.07 16:58
Ich habe auch nur überfolgen, aber du solltest vielleicht die Variable "raus" global definieren und nicht lokal.
Dann müsste er auch bei den rekursiven Durchläufen rausspringen.
"raus" musst du natürlich dann vor dem ersten Aufruf der Prozedur einmal auf false setzen, und nicht jedesmal rekursiv in der Prozedur.
Christian S. - Mo 08.01.07 17:02
Könnte man nicht eine Exception werfen, welche dann "nach oben" weiter gereicht wird?
Martok - Mo 08.01.07 17:07
Christian S. hat folgendes geschrieben: |
Könnte man nicht eine Exception werfen, welche dann "nach oben" weiter gereicht wird? |
Autsch. Das meinst du jetzt nicht ernst, oder? Exceptions sind Ausnahmen, kein Mittel zur Flusskontrolle.
Für sowas sollte die rekursive Funktion eher einen Rückgabewert bekommen, der den aufrufenden Funktionen sagt: beende dich!
Christian S. - Mo 08.01.07 17:19
Martok hat folgendes geschrieben: |
Christian S. hat folgendes geschrieben: | Könnte man nicht eine Exception werfen, welche dann "nach oben" weiter gereicht wird? |
Autsch. Das meinst du jetzt nicht ernst, oder? Exceptions sind Ausnahmen, kein Mittel zur Flusskontrolle. |
Zum einen sehe ich keinen Grund, mir meine Möglichkeiten selber zu verbauen und sklavisch und undifferenziert an irgendwelchen Regeln festzuhalten. Zum anderen
ist ein solches Beenden einer Rekursion wohl eine Ausnahme, denn im Normalfall sollte das bei einer Rekursion nicht nötig sein.
D. Annies - Mo 08.01.07 17:57
Hi, Delpher,
scheint ja gar nicht so einfach zu sein..., obwohl ich meine, dass ich vor der eigentlichen Rekursion abbrechen will.
Das mit der globalen Variablen habe ich überprüft - njet.
Bis denne, Detlef
jasocul - Mo 08.01.07 18:03
Du musst Dein "raus" "durchreichen". Sonst weiß die aufrufende Prozedur ja nicht, dass die Rekursion ein Abbruch-Kriterium bekommen hat. Das ginge zum Beispiel mit einem Var-Parameter des Prozeduraufrufs. Zusätzlich solltest Du den Wert von "raus" auch in Deinen Schleifen abfragen, damit diese nicht weiterlaufen.
D. Annies - Mo 08.01.07 19:00
Hi, Peter,
das hört sich gut an, ich versuch's mal und melde mich dann wieder...
bis denne, Detlef
D. Annies - Mo 08.01.07 19:51
HI, ...
ich krieg's nicht hin!
Habe die Deklaration ergänzt durch ...(...; var raus: boolean);
setze in der Proc raus auf true,
und rufe mit ...(..., raus) wieder auf
kompiliert fehlerfrei, aber bricht nicht ab. Ich habe zwar schon mit var-Parametern gearbeitet, aber ich sehe hier den Fehler nicht.
Kann nochmal jemand helfen?
Danke, Detlef
D. Annies - Mo 08.01.07 20:39
Ha, es hat sich doch etwas (eine Menge) getan:
Die Rekursion wird abgebrochen, wenn das aktuelle Verzeichnis abgefragt ist, ein Wechsel in ein andreres UV findet nicht mehr statt!
Das ist es dann wohl - noch mals danke für den VAR-Tipp!
Gruß, Detlef
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!