kostenloser Webspace werbefrei: lima-city


Rekursions Problem

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    ttobsen

    Kostenloser Webspace von ttobsen

    ttobsen hat kostenlosen Webspace.

    Und nochmal ich. Da der Thread allerdings ein neues Problem behandelt mach ich auch nenn neuen auf.

    Folgender Code:

    void Verzeichnis(string Dirname)
    {
        DIR *hdir;
        struct dirent *entry;
        
        string TempFile, TempInfo;
        string TempExt;
        int TempInt;
    
        hdir = opendir(Dirname.c_str());
        
        do
        {
            entry = readdir(hdir);
            
            
            if (entry)
            {
                TempFile = entry->d_name;
                TempExt = DateiErweiterung(TempFile);
                
                if ((TempFile != ".") and (TempFile != ".."))
                {
                    
                    if (opendir(entry->d_name) == NULL)
                    
                    {
                        if (UnerlaubteErweiterung(TempExt) == true)
                        {
                            cout << Dirname << "/" <<TempFile << " : ist nicht erlaubt\n";
                        }
                        else
                        {
                            cout << Dirname << "/" << TempFile << " : ist erlaubt\n";
                        }
                    }
                    else
                    {
                        Verzeichnis(Dirname+"/"+TempFile);
                    }
                }
            }
        } while (entry);
        closedir(hdir);
    }


    Das ganze soll mir rekursiv Dateien auflisten, aus dem gegebenen Verzeichnis. Die Funktionen UnerlaubteErweiterung() und Erweiterung() funzen tadellos. Eigentlich funktioniert alles tadellos, ausser das wenn ein Verzeichnis mehr als einen Unterordner hat es einen Speicherfehler gibt: "Die Anweisung xxx verweist auf den speicher xxx, usw.."

    Ich habe so das Gef?hl das das Problem bei der Zeigergeschcihte am Anfang liegt, allerdings hab ich 0 Plan warum genau das nicht funktioniert.

    F?r Hilfe wie immer seeeeehr dankbar ;)

    Gru? Tobi
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. t***a

    Hi tobi,

    poste doch mal den kompletten Code. Also gezippt auf deiner Website zB. Kann mir vorstellen, dass es die Fehlersuche um einiges erleichtern w?rde.

    Gru? talpa

    Beitrag ge?ndert am 5.11.2005 14:15 von talpa
  4. Autor dieses Themas

    ttobsen

    Kostenloser Webspace von ttobsen

    ttobsen hat kostenlosen Webspace.

    hehe der komplette Code posten bringt zwar nicht viel weil das nur der Funktionsaufruf ist, abr bitte. Das seltsame ist, das ich noch hinzugef?gt habe das er das ganze noch in eine DAtei schreiben soll und irgendwie klappts jetzt, seeeeh bizzar:

    #include <dirent.h>
    #include <iostream.h>
    #include <fstream.h>
    #include <string>
    using std::string;
    
    const char AusgabeDateiname[] = "./Ausgabe.txt";
    ofstream AusgabeDatei(AusgabeDateiname);
    
    string DateiErweiterung(string Dateiname);
    bool UnerlaubteErweiterung(string Erweiterung);
    void Verzeichnis(string Dirname);
    
    
    int main()
    {
        cout << "Content-type: text/html\n\n";
        Verzeichnis(".");
        AusgabeDatei.close();
           
        system("PAUSE");
        return 0;
    }
    
    string DateiErweiterung(string Dateiname)
    {
        int i = 0;
        int k = 0;
        string ReturnWert = "";
        
        while (Dateiname[i] != '.')
        {
            i++;
        }
        
        for (k=i; k < strlen(Dateiname.c_str()); k++)
        {
            ReturnWert += Dateiname[k];
        }
        return ReturnWert;
    }
    
    bool UnerlaubteErweiterung(string Erweiterung)
    {
        bool ReturnAusgabe = false;
        string Erweiterungen[] = {".o", ".cpp", ".bmp", ".dll", ".txt"};
        int length = 5;
        
        for (int i = 0; i<length; i++)
        {
            if (Erweiterung == Erweiterungen[i])
            {
                ReturnAusgabe = true;
                break;
            }
        }
        return ReturnAusgabe;
    }
    
    void Verzeichnis(string Dirname)
    {
        DIR * hdir;
        struct dirent * entry;
        
        string TempFile, TempInfo;
        string TempExt;
        int TempInt;
    
        hdir = opendir(Dirname.c_str());
        
        do    
        {              
            entry = readdir(hdir);
            if (entry)
            {
                TempFile = entry->d_name;
                TempExt = DateiErweiterung(TempFile);
                
                if ((TempFile != ".") and (TempFile != ".."))
                {
                    
                    if (opendir(entry->d_name) == NULL)
                    {
                        if (UnerlaubteErweiterung(TempExt) == true)
                        {
                            cout << Dirname << "/" <<TempFile << " : ist nicht erlaubt\n";
                            AusgabeDatei << Dirname << "/" <<TempFile << "\n";
                        }
                        else
                        {
                            cout << Dirname << "/" << TempFile << " : ist erlaubt\n";
                            
                        }
                    }
                    else
                    {
                        Verzeichnis(Dirname+"/"+TempFile);
                    }
                }
            }
        }  while (entry);
        closedir(hdir);
    }


    Naja, wer ne Idee hat warum es jetzt funktioniert und es mir sagen w?rde, w?re voll supi.

    Aber eine frage hab ich noch:

    DIR * hdir;
    struct dirent * entry;


    Was genau sagt diese Zeile? Ist DIR ein datentyp, der in dirent.h drinnen steckt? Was beeutet die andere Zeile? Bedeutet es das ein Zeiger auf dirent erzeugt wird? Was ist dann das struct?

    Vielen Fragen ;)

    Gru? Tobi

    Edit:

    Setlsam. Mir ist gerae aufgefallend as wenn ich aus der Dev-C++ Umgebung das Programm starte es keine Fehlermeldung gibt und wenn ich es so ?ffne aus Windows herraus gibt es wieder die Fehlermeldung von oben.

    Noch ein Edit:

    Alsod as Programm arbeitet doch so wie ich m?chte, allerdings habe ich ein Problem wenn in einem Verzeichnisnamen der durchsucht werden soll ein Leerzeichen vorkommt. Wie kann ich das Problem l?sen?

    Beitrag ge?ndert am 5.11.2005 15:48 von ttobsen

    Beitrag ge?ndert am 5.11.2005 17:03 von ttobsen
  5. t***a

    hmm, das Leerzeichenproblem hab ich noch nicht festgestellt, aber ich habe zwei andere Dinge gefunden.

    1. In der Funktion DateiErweiterung(..) kann die Variable i ins Nirwana abhauen, wenn eine Datei keinen "." enth?lt. Das trifft auch auf Verzeichnisnamen zu. Das f?hrt dann unterbestimmten Bedingung zu einem "Die Anweisung verweist auf..."-Fehler.
    Du solltest das vielleicht so machen :

    while (Dateiname.at(i) != "." && i < Dateiname.size())

    Ausserdem 'strlen(Dateiname.c_str)' ist unn?tig, wenn man schon string benutzt. Besser:

    Dateiname.size()

    Wenn man eh string benutzt k?nnte es zB auch so aussehen:

    if(Dateiname.find("."))
    ReturnWert = Dateiname.substr(Dateiname.find("."),Dateiname.size());


    2. Die Funktion Verzeichnis(..) sucht bei Unterverzeichnissen nur in der n?chsttieferen Ebene. Wenn du Unterverzeichnisse in einem Unterverzeichnis hast usw. werden diese nicht mehr gefunden.
    Um das zu ?ndern m?sstest du bspw.

    if (opendir(entry->d_name) == NULL)

    durch

    strPath = Dirname + "/" + TempFile;
    if (opendir(strPath.c_str()) == NULL)


    ersetzen. Damit der relative Bezug zu deinem Startverzeichnis stimmt.

    Viel Spass beim hacken,
    talpa


    p.s.: Menno, die Formatierung hier im Forum macht mich nochmal fertig.

    Beitrag ge?ndert am 5.11.2005 18:30 von talpa
  6. Autor dieses Themas

    ttobsen

    Kostenloser Webspace von ttobsen

    ttobsen hat kostenlosen Webspace.

    arrr der Post erinnert mich gerade das ich doch noch was aus dem Thread machen wollt:

    http://www.lima-city.de/boards.php?m=thread&id=38943

    der erste Post von 0-Checka.

    Jetzt funzt es auch so wie ich mag freu.

    string DateiErweiterung(string Dateiname)
    {
        int i = 0;
        int k = 0;
        string ReturnWert;
           
        i = Dateiname.find_last_of('.');
        if (i >= 0)
        {
            ReturnWert = Dateiname.substr(i, strlen(Dateiname.c_str()));
        }
        else
        {
            ReturnWert = "";
        }
        
        return ReturnWert;
    }


    Das mit der Verzeichnistiefe funktioniert allerdings! Die Funktion wird sschlie?lich rekursiv aufgerufen.

    Gru? Tobi

    Edit:

    Hab jetzt bermekrt das ich den L?sungsweg doch einschlagen mu? um das Ergebnis zu erzielen. Danke nochmal!

    Beitrag ge?ndert am 5.11.2005 22:09 von ttobsen
  7. t***a

    Das mit der Verzeichnistiefe funktioniert allerdings! Die Funktion wird sschlie?lich rekursiv aufgerufen.


    Das wundert mich aber nun doch. Denn der Befehl opendir(param) bekommt als Parameter den Pfad ?bermittelt, soweit ich das verstanden habe. Jedenfalls braucht es da entweder eine absolute Angabe ( C:/Verz1/DateiX.txt ) oder eine relative Angabe ( ./Filme/Terminator.avi). Wenn jetzt die rekursive Funktion Verzeichnis(..) f?r ein Unterverzeichnis aufgerufen wird, werden zwar noch alle Dateien und Verzeichnisse in dem Unterverzeichnis ausgelesen, aber die Zeile

    if (opendir(entry->d_name) == NULL)

    liefert immer das Ergebnis NULL und somit werden alle Eintr?ge als Dateien klassifiziert. Das heisst Unterverzeichnis der 2.Ebene (Unter-Unterverzeichnisse) werden nicht ber?cksichtigt. Probier es doch einfach mal mit einer Verzeichnisstrukur mit 2 oder 3 Ebenen aus. Durch den Vergleich des Ergebnisses von opendir mit Null wird n?mlich nur angedeutet, dass opendir fehlgeschlagen ist und nicht, dass der ?bergeben Pfad/Dateiname auf eine Datei zeigt.


    Und nochmal:

    strlen(Dateiname.c_str())

    k?rzer, sch?ner und mehr sexy ist :

    Dateiname.size()

    In diesem Sinne:
    0 ist false, alles andere true

    talpa

    ->

    Beitrag ge?ndert am 5.11.2005 22:51 von talpa
  8. 0******a

    Ob etwas ein Verzeichnis ist oder nicht sollte man sowieso lieber per stat() ?berpr?fen.
    Und das system("pause") am Ende ist auch keine sch?ne L?sung (funzt nicht unter Linux). Mal hier im Forum suchen, die saubere L?sung wurde mehrmals beschrieben.
  9. Autor dieses Themas

    ttobsen

    Kostenloser Webspace von ttobsen

    ttobsen hat kostenlosen Webspace.

    0-checka schrieb:
    Ob etwas ein Verzeichnis ist oder nicht sollte man sowieso lieber per stat() ?berpr?fen.
    Und das system('pause') am Ende ist auch keine sch?ne L?sung (funzt nicht unter Linux). Mal hier im Forum suchen, die saubere L?sung wurde mehrmals beschrieben.


    Das mit stat() habe ich irgendwie nicht hinbekommen. Das system('pause') mu? eh ganz weg, weil das ganze was cgi technisches werden soll, da brauch ich das garnicht. Dev-Cpp macht das halt von anfang an rein.

    @talpa:

    Das hatte nur funktioniert wenn ich als Startverzeichnis ein '.' genommen habe. Allerdings nicht wenn ich euinen absoluten Dateipfad gew?hlt habe. Jetzt funzt es *freu*.

    Das Opendir(entry-d_name) war ja nur zum pr?fen ob es sich um ein Verzeichnis oder eine Datei handelt. Das zu ?ffnende Verzeichnis wird ja an readdir() ?bermittelt.

    Ok das mit size wurde ge?ndert.

    Gru? Tobi und nochmals voll fett donk ey ;)
  10. t***a

    versuch mal das:

    stat(strFileName.c_str(),&buf);

    if(buf.st_mode & _S_IFDIR)

    cout << strFileName << " is a directory." << endl;

    else if(buf.st_mode & _S_IFREG)

    cout << strFileName << " is a file" << endl;

    else

    cout << "kaputt" << endl;

    --------------------------------------------
    "Nachsatz: deshalb mag ich Bin?rtechnik. Da gibt es nur drei Zust?nde: High, Low und Kaputt."

    Beitrag ge?ndert am 8.11.2005 00:01 von talpa
  11. Autor dieses Themas

    ttobsen

    Kostenloser Webspace von ttobsen

    ttobsen hat kostenlosen Webspace.

    Das mit stat() hatte ich dann mittlerweile doch gel?st, aber trotzdem danke :)

    Gru? Tobi
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!