IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[Débutant] FindFirstFile, FindNextFile, FindClose récursif


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 9
    Par défaut [Débutant] FindFirstFile, FindNextFile, FindClose récursif
    Salut !

    j'essaye de lister tous les fichiers d'un repertoire et de ces sous-repertoire

    j'imagine que ce sujet a dù etre traiter plusieurs fois dans ce forum
    et je m'en excuse, j'ai pas trouver, ce topic si il existe

    j'ai piquer du code ici et là nottament dans la FAQ C, ca liste trés bien
    un répertoire mais pour les sous-répertoire ca marche pas
    nottament quand j'essaye de faire un appel récursif

    je travail avec Dev-C++ sous Windows xp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <iostream> 
    #include <windows.h>
     
    using namespace std;
     
    bool lister(char* pszMask) 
    {
         WIN32_FIND_DATA File;
         HANDLE hSearch;
         BOOL bFindNextFile;  //vrai si il ya un fichier ou un repertoire suivant
     
         hSearch = FindFirstFile(pszMask, &File);
         if(hSearch == INVALID_HANDLE_VALUE){
             return FALSE;
         }
     
         // Partie qui retourne le répertoire courant dans BufCurDir
         TCHAR BufCurDir[MAX_PATH];
         DWORD dwRet;
         dwRet = GetCurrentDirectory(MAX_PATH, BufCurDir);
         //------
     
         bFindNextFile = TRUE;
         do {
     
            if (File.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
               {
               // Traite les Repertoires
               if(File.cFileName[0] != '.') // ne traite pas "." et ".."
                 {
                  SetCurrentDirectory(File.cFileName);
                  lister(pszMask);           //<--------------- je me plante ici
                  //cout << BufCurDir << '\\' << File.cFileName << endl;
                 }
               }
            else
               {
               // Traite les Fichiers
               cout << BufCurDir << '\\' << File.cFileName << endl; 
               }
     
            bFindNextFile = FindNextFile(hSearch, &File);
         } while(bFindNextFile); //tantqu'il existe un fichier ou répertoire suivant 
     
         FindClose(hSearch);
         return TRUE;
    }
     
    int main(int argc, char *argv[])
    {
        lister("*");
        system("PAUSE"); 
        return EXIT_SUCCESS;
    }
    Voila si quelqu'un pouvais m'aider comme d'hab ce serai super sympa

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut hop
    C'est quoi ton "plantage" t'as quoi comme error ??

  3. #3
    Membre émérite Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Par défaut
    Bonjour,

    c'est ici que ça pêche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main(int argc, char *argv[]) 
    { 
        lister("*"); // "*" n'est pas autorisé pour les nom de répertoires !
        system("PAUSE"); 
        return EXIT_SUCCESS; 
    }
    Tout est dans le commentaire.

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Ça doit plutôt être
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 9
    Par défaut
    Salut a tous et merci pour votre aide

    chronos, le programme plante pas; mais ne fais pas ce que je voudrais
    dans les commentaire de mon code j'ai mis "je me plante ici",
    c'est quand j'essaye de faire un appel récursif que je mis prend mal

    caine, si si ca marche "*" ou "*.*", quand je veux lister les fichiers
    d'un repertoire, il me prend aussi les sous-repertoire, de toute maniére
    je liste les sous-repertoire que pour avoir la liste des fichiers a l'intérieur

    Trap D, quand je mais "." comme masque de saisi, le programme ne me
    sort que le nom du répertoire courant, logique, si je met "..", il me
    sort le nom du répertoire parent

    bon je vais essayer de rétrécir le code en supprimant ce qui sert a
    rien mais ya pas grand chose a enlever :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <iostream> 
    #include <windows.h>
     
    using namespace std;
     
    bool lister(char* pszMask) 
    {
         WIN32_FIND_DATA File;
         HANDLE hSearch;
         BOOL bFindNextFile;  //vrai si il ya un fichier 
                                        //ou un repertoire suivant
     
         hSearch = FindFirstFile(pszMask, &File);
         if(hSearch == INVALID_HANDLE_VALUE){
             return FALSE;
         }
     
         bFindNextFile = TRUE;
         do {
     
            if (File.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
               {
               // Traite les Repertoires
               if(File.cFileName[0] != '.') //ne traite pas "." et ".."
                 {
                  SetCurrentDirectory(File.cFileName);
                  //lister(pszMask);   //<------ je me plante ici
                  cout << File.cFileName << endl; // --- pour les tests
                 }
               }
            else
               {
               // Traite les Fichiers
               cout << File.cFileName << endl; 
               }
     
            bFindNextFile = FindNextFile(hSearch, &File);
         } while(bFindNextFile); //tantqu'il existe un fichier 
                                          //ou répertoire suivant 
     
         FindClose(hSearch);
         return TRUE;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main(int argc, char *argv[])
    {
        lister("*");
        system("PAUSE"); 
        return EXIT_SUCCESS;
    }
    Alors j'ai fais différent tests en remplaceant l'appel recursif lister(pszMask);
    par cout << File.cFileName << endl; et donc

    pour lister("*"); :
    Dossier1
    Dossier2
    main.cpp
    main.o
    Makefile.win
    Projet1.dev
    Projet1.exe
    Projet1.layout
    Appuyez sur une touche pour continuer...
    pour lister("."); :
    456
    Appuyez sur une touche pour continuer...
    pour avec l'appel récursif lister("*"); :
    Dossier1.cpp
    Dossier1.exe
    Dossier1.o
    Dossier1.cpp
    Dossier1.exe
    Dossier1.o
    main.cpp
    main.o
    Makefile.win
    Projet1.dev
    Projet1.exe
    Projet1.layout
    Appuyez sur une touche pour continuer...
    Voici l'arborescence de mon répertoire :

    D:\Dev-Cpp\PROJET\456 :

    - Dossier1
    ------------Dossier1.exe
    ------------Dossier1.cpp
    ------------Dossier1.o
    - Dossier2
    ------------Dossier2.txt
    Projet1.exe
    main.cpp
    Projet1.dev
    Projet1.layout
    main.o
    Makefile.win

  6. #6
    Membre confirmé
    Homme Profil pro
    Dev C++, CUDA
    Inscrit en
    Mai 2005
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Nouvelle-Zélande

    Informations professionnelles :
    Activité : Dev C++, CUDA
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2005
    Messages : 83
    Par défaut
    Je comprend pourquoi il ne rentre pas dans le 2e dossier :
    Pour le 1er dossier, t'as un SetCurrentDirectory(File.cFileName); puis tu appel recursif => ca liste ce qu'il y a dans dossier1. Mais une fois fini le dossier on revient dans le premier appel de lister, donc on est sense etre dans ton folder de depart mais en fait tu n'as pas re fait un SetCurrentDirectory(".."); => tu est toujours dans Dossier1 et donc il reliste dossier1. Ca explique pourquoi tu as le contenu de Dossier1 en double.

    Par contre j'ai pas compris pourquoi il liste toujours le contenu de 456. D'apres ce que j'ai compris, il doit lister 2 fois Dossier1 et c'est tout ....

    Solution :
    apres l'appel recursif il faudrait ajouter une ligne de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                  SetCurrentDirectory(File.cFileName);
                  lister(pszMask);   //<------ je me plante ici
                  SetCurrentDirectory(".."); // => pour revenir dans le dossier actuel

    J'espere que c'est comprehensible. J'arrive pas a etre plus clair ....

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Déjà, en récursif (et surtout en C/C++ !!), il est dangereux de passer tes propres arguments (pszMask) aux appels récursifs. Lorsque ce sont des pointeurs, c'est la donnée "d'origine" qui va être modifiée, et au retour à l'appelant, ce paramètre sera invalide !!

    Sinon, j'ai vu ça comme problèmes potentiels :
    - Tu affiche le nom du répertoire [i]après[/b] avoir fait l'appel récursif, ce n'est pas une bonne idée.
    - Comme te l'as fait remarquer mhtrinh, tu ne restaures pas le répertoire courant : c'est pas bien.
    En dehors de ça, ton programme n'a pas planté chez moi...

    Après, ta manière de lister est assez étrange, car tu appliques le masque (pszMask) partout, y compris aux répertoires... Bizarre, ton truc, car avec un masque "def*", un fichier "default.txt" ne serait pas visible s'il était dans un sous-répertoire "Test", mais le serait dans un sous-répertoire "DefTest" !
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 9
    Par défaut
    Merci beaucoup a vous tous !

    mhtrinh, c'était effectivement ca

    Mac LAK, je parler pas du programme qui ce planter
    mais de moi, je comprennai pas. (je me suis mal exprimer désoler)

    et c'est pas important pour moi qu'il ne liste pas "def*", dans un dossier
    "test" mon but etait de lister tous les fichiers (sans les repertoires)
    je ne comptais pas changer le mask "*"

    Bye et reMerci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/09/2010, 11h05
  2. [Débutant] Comportement du cp récursif
    Par WerKa dans le forum Linux
    Réponses: 7
    Dernier message: 29/06/2008, 13h29
  3. Comportement étrange de FindFirstFile / FindNextFile
    Par stof dans le forum Visual C++
    Réponses: 4
    Dernier message: 29/01/2007, 12h56
  4. XPATH XSL Récursif (très débutant!)
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 24/08/2004, 10h04
  5. Réponses: 2
    Dernier message: 29/08/2003, 17h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo