Autor |
Beitrag |
D. Annies
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Mo 08.01.07 15:57
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.
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
      
Beiträge: 1383
Erhaltene Danke: 1
WinXP
D2005 PE
|
Verfasst: 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.
Zuletzt bearbeitet von Coder am Mo 08.01.07 16:31, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: 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
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Chatfix
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: 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.
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 08.01.07 17:02
Könnte man nicht eine Exception werfen, welche dann "nach oben" weiter gereicht wird?
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: 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!
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: 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.
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: 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 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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
|
|
|