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 :

Problème de récursion pour rechercher des fichiers (FindFirstFile)


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 167
    Par défaut Problème de récursion pour rechercher des fichiers (FindFirstFile)
    Bonsoir,

    Alors voila j'ai voulu faire un petit programme en C qui réalise des recherches de fichiers sur le dossier courant, sur le dossier spécifié en argument etc.. mais à chaque fois ces recherches sont uniquement valables pour le dossier indiqués.

    Or moi j'aimerais également offrir la possibilité de faire une recherche de fichier dans tous les sous-dossiers du répertoire courant.

    J'ai pensé bon d'utiliser une récursion qui pour chaque dossier détecté, applique la récursion en mettant à jour bien sur le chemin d'accès.

    Mais voila cette fonction ne marche pas, j'atteins le cas d'erreur "INVALID_HANDLE_VALUE".

    Je ne comprends pas où est le problème dans tout ça.

    Voici pour mieux illustrer le petit bout de code:

    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
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
     
    void recherche(int choix2, char* path, char* slash, HANDLE hSearch, WIN32_FIND_DATA File, LARGE_INTEGER filesize) {
     
         if (path == NULL) {
            hSearch = FindFirstFile(slash, &File);
         }else{  
                 hSearch = FindFirstFile(strcat(path,slash), &File);
         }
         if (hSearch != INVALID_HANDLE_VALUE) {
            printf("Liste des fichiers: \n\n");
            do {
     
               if (File.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // Si c'est un dossier
                  printf("%s   <DIR>\n", File.cFileName);
                  if (choix2 == 3) {
                     recherche(choix2, strcat(path,File.cFileName), slash, hSearch, File, filesize);
                  }
               }else{      
                  filesize.LowPart = File.nFileSizeLow;
                  filesize.HighPart = File.nFileSizeHigh;
                  printf("%s %ld bytes\n", File.cFileName, filesize.QuadPart);
                                     }
            } while (FindNextFile(hSearch, &File));                        
               FindClose(hSearch);
     
         }else{
               printf("Erreur");
         }
    }
     
     
     
    int main(int argc, char *argv[]) {
     
        WIN32_FIND_DATA File;
        LARGE_INTEGER filesize;
        HANDLE hSearch;
        int choix1 = 0, choix2 = 0;
        char* path = NULL;
        char* nom = NULL;
        char slash[20] = "/";
     
     
     
     
             printf("\n\nQue voulez-vous faire?\n\n1 - Effectuer une recherche de fichier\n2 - Stocker un fichier dans mon catalogue\n3 - Quitter\n\n");
             scanf("%ld", &choix1);
     
        if (choix1 == 1) {
           nom = (char *)malloc (20*sizeof(char));
           printf("Entrez le nom du fichier que vous voulez chercher :\n\n");
           scanf("%s", nom);
           strcat(slash,nom);
           printf("\n1 - Effectuer une recherche dans le dossier courant\n2 - Effectuer une recherche dans la corbeille\n3 - Effectuer une recherche sur tout l'ordinateur\n4 - Effectuer une recherche personnalisée\n\n");
           scanf("%ld", &choix2);
     
           switch(choix2) {
                         case 1:
                              printf("Recherche dans le dossier courant en cours...\n\n");
                              recherche(choix2, path, nom, hSearch, File, filesize);
                              break;
                         case 2:
                              printf("Recherche dans la corbeille en cours...\n\n");
                              //slash = (char *)malloc (22*sizeof(char));
     
                              break;
                         case 3:
                              path = (char *)malloc (50*sizeof(char));
                              printf("Veuillez taper le chemin complet du dossier de départ :\n\n");
                              scanf("%s", path);
                              printf("Recherche sur tout l'ordinateur en cours...\n\n");
                              recherche(choix2, path, slash, hSearch, File, filesize);
                              break;
                         case 4:
                              path = (char *)malloc (50*sizeof(char));
                              printf("Veuillez taper le chemin complet du dossier à scanner :\n\n");
                              scanf("%s", path);
                              recherche(choix2, path, slash, hSearch, File, filesize);
                              break;
           }
     
        }else if (choix1 == 2) {
              return 0;
        }else{
              return 0;
        }
     
      printf("\n");
      system("PAUSE");
      return 0;
    }
    Je vous remercie de l'intérêt que vous voudrez bien apporter à mon problème

    Raiden

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    FindFirstFile(slash, &File);: slash vaut quoi? Au moins quelque chose comme '*'?

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je ne vois aucune allocation de mémoire dans ce que tu fais...
    Je vois plutôt un squelette de ce genre:
    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
    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
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
     
    /* Une fonction assez efficace pour combiner deux chemins: O(2*(n+m)).
       Note: Cette fonction est différente de la fonction .Net System.Io.Path::Combine(),
       car elle assemble systématiquement les deux chemins, plutôt que n'utiliser que droit
       si droit commence par un séparateur */
    char * CombinePath(char const * const gauche, char const * const droit)
    {
    	size_t const cchLongGauche = strlen(gauche);
    	size_t const cchLongDroit = strlen(droit);
    	int const bSeparateurGauche = (cchLongGauche > 0 && (gauche[cchLongGauche-1]=='\\' || gauche[cchLongGauche-1]=='/'));
    	int const bSeparateurDroit = (cchLongDroit > 0 && (droit[0]=='\\' || droit[0]=='/'));
    	/* Supprimer un caractère si séparateur des deux cotés, en ajouter un si aucun séparateur */
    	int const nSeparateurARajouter = (bSeparateurGauche ? 0 : 1) + (bSeparateurDroit ? 0 : 1) - 1;
    	size_t const cchLongBuffer = cchLongGauche + cchLongDroit + nSeparateurARajouter;
    	size_t const cchTailleBuffer = cchLongBuffer + 1;
     
    	char *buffer = malloc(cchTailleBuffer * sizeof(*buffer));
    	if(buffer != NULL)
    	{
    		size_t curIndex = 0;
    		#ifdef _CRT_INSECURE_DEPRECATE
    			/*Version pour Visual 2005*/
    			strcpy_s(buffer + curIndex, cchTailleBuffer-curIndex, gauche);
    			curIndex += cchLongGauche;
    			if(!bSeparateurGauche)
    			{
    				buffer[curIndex++] = '\\';
    				buffer[curIndex] = '\0';
    			}
    			strcpy_s(buffer + curIndex, cchTailleBuffer-curIndex, droit + (bSeparateurDroit ? 1 : 0));
    			curIndex += cchLongDroit - (bSeparateurDroit ? 1 : 0);
    		#else
    			/*Version normale, portable*/
    			strcpy(buffer + curIndex, gauche);
    			curIndex += cchLongGauche;
    			if(!bSeparateurGauche)
    			{
    				buffer[curIndex++] = '\\';
    				buffer[curIndex] = '\0';
    			}
    			strcpy(buffer + curIndex, droit + (bSeparateurDroit ? 1 : 0));
    			curIndex += cchLongDroit - (bSeparateurDroit ? 1 : 0);
    		#endif
    		/*On asserte qu'on a bien rempli le buffer à fond*/
    		assert(curIndex == cchLongBuffer);
    	}
    	return buffer;
    }
     
    void FreePath(char *del)
    {
    	free(del);
    }
     
     
    void recherche(char const *dossier)
    {
    	char * chemin = CombinePath(dossier, "*");
    	if(chemin != NULL)
    	{
    		WIN32_FIND_DATAA donneesSurFichier;
    		HANDLE hFind = FindFirstFileA(chemin, &donneesSurFichier);
    		if(hFind == INVALID_HANDLE_VALUE)
    		{
    			/* Echec */
    			/* ... */
    		}
    		else
    		{
    			BOOL bSuivant;
     
    			/* Début d'analyse du répertoire */
    			/* ... */
     
    			do
    			{
    				/* Fichier trouvé */
    				BOOL bRepertoire = FALSE;
    				/* ... */
     
    				if((donneesSurFichier.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0)
    				{
    					if(strcmp(donneesSurFichier.cFileName, ".")!=0 && strcmp(donneesSurFichier.cFileName, "..")!=0)
    					{
    						/* Le fichier est un sous-répertoire */
    						char * sousDossier;
    						bRepertoire = TRUE;
    						/* ... */
     
    						sousDossier = CombinePath(dossier, donneesSurFichier.cFileName);
    						if(sousDossier!=NULL)
    						{
    							recherche(sousDossier);
    							FreePath(sousDossier);
    						}
    					}
    				}
     
    				/* On sait si le fichier est un sous-répertoire ou non */
    				/* ... */
     
    				bSuivant = FindNextFileA(hFind, &donneesSurFichier);
    			}
    			while(bSuivant);
     
    			/* Fin d'analyse du répertoire */
    			/* ... */
     
    			FindClose(hFind);
    		}
    		FreePath(chemin);
    	}
    }
    Bien entendu, ce n'est pas ce qu'il y a de plus performant côté exécution (on fait deux appels à CombinePath() pour chaque sous-dossier), mais ce n'est rien comparé aux temps d'accès disque de toute façon...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Progress bar class pour recherche des fichiers
    Par Montor dans le forum Contribuez
    Réponses: 0
    Dernier message: 21/08/2010, 19h50
  2. Réponses: 1
    Dernier message: 15/10/2008, 17h56
  3. Code source pour rechercher des fichiers Mp3 sur le disque
    Par specta61 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/02/2007, 19h49
  4. [win] problème pour partager des fichiers entre 2 pc
    Par goma771 dans le forum Administration
    Réponses: 1
    Dernier message: 01/12/2005, 16h15
  5. Problème pour Télécharger des fichiers
    Par joce3000 dans le forum C++Builder
    Réponses: 8
    Dernier message: 21/01/2005, 10h30

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