rekursive funktion bricht ab?



  • 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 🙄

    http://c-plusplus.net/forum/viewtopic.php?t=16725



  • 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 🙂


Anmelden zum Antworten