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 régulier
    Inscrit en
    Novembre 2006
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 167
    Points : 85
    Points
    85
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    FindFirstFile(slash, &File);: slash vaut quoi? Au moins quelque chose comme '*'?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 575
    Points
    41 575
    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...

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