rekursive funktion bricht ab?
-
Hi leute,
ich wollte mirn kleines programm schreiben, das mir jeden dateinamen aller meines mainordners unterordner in eine datei schreibt.
Da ich nicht weiß wieviele verzeichnisse, bzw. unterverzeichnisse es gibt, dachte ich mir, dass eine rekursive funktion hier wohl angemessen wäre.
Aber nachdem die funktion sich einmal selbst aufgerufen hat, wird sie wieder beendet. Ist das immer so? Dann würds aber doch rekursive funktionen überhaupt nicht bringen?
-
Wenn du in der Funktion die Funktion aufrufst nicht - bis dies einmal nicht mehr geschieht und es wieder rückwärts geht (und alle Funktionen wieder zurückkehren)
Zeig mal ein bisschen Code

-
void scan_directory(std::string path) { HANDLE search; WIN32_FIND_DATA File; bool did = false; for(search = FindFirstFile(path.c_str(), &File); GetLastError() != ERROR_NO_MORE_FILES; FindNextFile(search, &File)) { if(did == false) { path = path.substr(0, path.length() - 1); did = true; } MessageBox(NULL, File.cFileName, "", MB_OK); if(File.dwFileAttributes != FILE_ATTRIBUTE_ARCHIVE) { if((strlen(File.cFileName) != 1) && (strlen(File.cFileName) != 2)) { std::string newpath = path + File.cFileName + "\\*"; scan_directory(newpath); } } else { out << File.cFileName << '\n'; } } FindClose(search); }
-
Was soll der Check "File.dwFileAttributes != FILE_ATTRIBUTE_ARCHIVE" und um . und .. rauszufiltern würde ich nicht nur checken, ob der datei/ordnername min. 3 Zeichen lang ist (es gibt auch gültige 1 und 2 Zeichen lange
)
Außerdem bekommst du doch, wenn du das \* schon vor dem Funktionsaufruf anhängst und an den übergeben Pfad innerhalb der Funktion wieder den Verzeichnisnamen dranhängst einen Pfad der bald sehr viele \* enthält
Lass dir aber doch zum Test erstmal einfach die Dateinamen ausgeben und ob es ein Verzeichnis ist, oder nicht (damit du mal siehst, ob die Sachen richtig eingeordnet werden

-
mit dem . & .. filtern hast recht, hab des nur letztens mit if cFileName == ".." probiert, aber ging nicht, dann wars mir zu dumm.
Aber an dem \* ist nichts falsch. Man muss das dir, das man durchsuchen will mit dem stern haben, und wenn dus nicht überlesen hast, filter ich das in der funktion auch wieder raus.if(did == false) { path = path.substr(0, path.length() - 1); did = true; }und der zeigt mir dann auch die ersten dateien an, dann geht er in den download ordner (der erste ordner), zeigt mir in dem die dateien an, aber wenn er fertig ist, zeigt er nichtmal mehr den rest der dateien im main-verzeichnis an.
-
und des beispiel bei der url die du mir gegeben hast hab ich jetzt mal ein bischen umgeschrieben, dass er mir auch alle dateien anzeigen soll.
Da geht er auch nur den ersten ordner durch, wobei er aber noch die anderen dateien probiert, die im mainverzeichnis sind.
-
Kleiner Tip:
Bei dem Scannen der Verzeichnisse würde ich nicht nur fragen ob es ein Verzeichnis ist, sondern auch ob es komprimiert ist etc....
Komprimierte Verzeichnisse gelten nicht mehr als FILE_ATTRIBUTE_DIRECTORY
Würde ich immer artig mit '|' abfragen.
-
DerAltenburger schrieb:
Der rekursive Aufruf startet FindFirst wiederholt. Wenn das Programm aus der Rekursion zurueckkommt, ist die Frage, ob die Daten in WIN32_FIND_DATA wfd von vorheriger Ebene wieder gueltig sind.
Bei mir (BCB) war der record zerstoert!!! Dann Rekursierte der sonstwohin.
Ich hab alle Ordner- Namen in einer Liste gespeichert und NACH FindClose erst die Rekursionen abgearbeitet! Da gings dann ohne Probleme
-
crash0r schrieb:
for(search = FindFirstFile(path.c_str(), &File); GetLastError() != ERROR_NO_MORE_FILES; FindNextFile(search, &File)) {sieht falsch aus. was schreibt denn die doku, woran man erkennt, ob FindNextFole geklappt hat. war das nicht der returnwert?
dann nimm den auch, verdammich.
mir scheint, du läßt dir nen laserror machen, der aber erst beim nachsten _fehler_ nen neuen wert annimmt und nicht bei der nächsten fehlerfreien funktion.for(search=FFF(...),ok=TRUE;ok;ok=FNF(...)){oder so.
-
is zwar in reinem c, funzt aber ganz gut:
#include <stdio.h> #include <stdlib.h> #include <windows.h> int scan_directory(char * path) { HANDLE search; WIN32_FIND_DATA File; BOOL did = FALSE; char buf[MAX_PATH]; int count=0; sprintf(buf,"%s\\*.*",path); search=FindFirstFile(buf, &File); if (search != INVALID_HANDLE_VALUE) do{ if( File.cFileName[0]!=46 ){ // . und .. nicht verwenden if( (File.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0){ //wenn verzeichnis dann nochmal rekursiv aufrufen sprintf(buf,"%s\\%s",path,File.cFileName); count=count+scan_directory(buf); }else{ count++; printf("%s\\%s\n",path,File.cFileName); } } }while(FindNextFile(search, &File)); FindClose(search); return count; } int main(int argc, char *argv[]){ int i=scan_directory("C:"); printf("%i Datei(en)\n",i); system("PAUSE"); return 0; }gruss,
matthias
-
achja, warums bei dir ned geht:
erstmal ists ned schön so eine for schleife zu verwenden, normalerweise packt man sowas in ne while schleife. for schleifen sind nur für das gedacht, das sie von i bis n zählen und sonst nichts anderes. es geht zwar, aber das ist eigentlich nicht sinn und zweck, sowas trägt nur zur verwirrung bei.
und dann, warum dieser vergleich:
if(File.dwFileAttributes != FILE_ATTRIBUTE_ARCHIVE)hier wird überprüft ob die datei das archiv attribut gesetzt hat oder nicht, ein verzeichnis kann aber genauso ein archiv attribut gesetzt haben wie eine normale date -> etwas willkürliche rekursive aufrufe, manchmal wohl auch bei dateien.
sonst eigentlich vom prinzip her richtig, ich habs allerdings nicht ausprobiert ob in dem for() was nicht stimmt, es müsste allerdings passen.
und noch was ist falsch in dem vergleich... dwFileAttributes enthält alle attribute einer datei, z.b.
(1. bit ist system, 2tes versteckt, 3. archiv und 4. schreibgeschützt)
0101
und wenn du jetzt einen vergleich machst mit archiv:
also
0010
->
if(0101!=0010)
ist das glaub ich ned das was du willst...wenn du aber die beiden werte bitweise undverknüpfst und dann auf !=0 überprüfst passts, also so:
if( (File.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0)
(man beachte die innere klammer :D)
gruss,
matthias
-
danke an euch alle, hat mir sehr geholfen.
-
Mir hat auch sehr geholfen
