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 :

Lister le contenu d'un dossier : crash à l'execution


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Mars 2017
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Mars 2017
    Messages : 59
    Par défaut Lister le contenu d'un dossier : crash à l'execution
    Bonjour à tous
    Je suis en train d'écrire une fonction pour lister récursivement le contenu d'un dossier et de ses sous-dossier.
    Pour l'instant, j'essayes simplement de lister le contenu du dossier de plus haut niveau (et pas les sous-dossiers).

    Lorsque je cherche seulement à afficher le contenu du dossier, aucun problème, mais quand j'essayes de stocker les noms de fichiers dans un tableau, le programme plante, alors qu'il n'y a aucun warning à la compilation.. Pouvez-vous m'aider ?


    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
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<dirent.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
     
    typedef enum
        {
            FICHIER, REPERTOIRE
        }TYPE_FICHIER;
     
    TYPE_FICHIER estRepertoire(const char* nomDuFichier)
    {
        struct stat statBuff;
        stat(nomDuFichier, &statBuff);
        if (S_ISDIR(statBuff.st_mode))
            return REPERTOIRE;
        else
            return FICHIER;
    }
     
    typedef struct
    {
        DIR* rep;
        char nom[20];
        int nombre_elements;
        char** elements;
    }REP;
     
    REP listerRepertoire (REP repertoireLu)
    {
        repertoireLu.rep = NULL;
        repertoireLu.nombre_elements = 0;
        struct dirent* fichierLu = NULL;
        char fichierType[15];
        int i;
     
        //On ouvre le repertoire
        repertoireLu.rep = opendir(repertoireLu.nom);
     
        if (repertoireLu.rep == NULL)
     //Message d'erreur d'ouverture
            perror("Error");
     
        //premiere lecture afin de determiner le nombre d'elements
        i=0;
        while ((fichierLu = readdir(repertoireLu.rep)) != NULL)
         {
             if (strcmp(fichierLu->d_name, ".")!=0 && strcmp(fichierLu->d_name, "..")!=0)
                i++;
         }
         closedir(repertoireLu.rep);
         repertoireLu.nombre_elements = i;
         printf("%i Fichiers\n",repertoireLu.nombre_elements);
     
        //on alloue un tableau pour stocker les noms de fichiers
         repertoireLu.elements = malloc((repertoireLu.nombre_elements +1) * sizeof(char*));
     
     
        //on relis le repertoire pour stocker les elements dans le tableau
         repertoireLu.rep = opendir(repertoireLu.nom);
         i=0;
         while ((fichierLu = readdir(repertoireLu.rep)) != NULL)
         {
             if (strcmp(fichierLu->d_name, ".")!=0 && strcmp(fichierLu->d_name, "..")!=0)
             {
                 i++;
                 if (estRepertoire(fichierLu->d_name) == REPERTOIRE)
                    strcpy(fichierType, "Dossier");
                else strcpy(fichierType, "Fichier");
                printf("%i : '%s'  %s\n", i, fichierLu->d_name, fichierType);
                repertoireLu.elements[i] = malloc(sizeof(fichierLu->d_name + 1)); //LIGNE AJOUTEE
                strcpy(repertoireLu.elements[i], fichierLu->d_name);
             }
         }
        return repertoireLu;
    }
     
     
    int main(int argc, char* argv[])
    {
        REP dossier_courant;
        strcpy(dossier_courant.nom, ".");
        int i;
     
        //on lit le dossier "."
        dossier_courant = listerRepertoire(dossier_courant);
     
        //affichage du tableau
        for (i=0; i<dossier_courant.nombre_elements; i++)
            printf("%s\n", dossier_courant.elements[i]);
     
     
        getchar();
     //pause
        return 0;
    }
    Exécution du code avec les lignes 74, 91 et 92 en commentaire (on a donc seulement affichage du contenu)
    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
    15 Fichiers
    1 : '1.txt'  Fichier
    2 : '1e dossier'  Dossier
    3 : '2.txt'  Fichier
    4 : '2e dossier'  Dossier
    5 : '3.txt'  Fichier
    6 : '4.txt'  Fichier
    7 : '5.txt'  Fichier
    8 : '6.txt'  Fichier
    9 : '7.txt'  Fichier
    10 : '8.txt'  Fichier
    11 : '9.txt'  Fichier
    12 : 'arborescence.c'  Fichier
    13 : 'arborescence.exe'  Fichier
    14 : 'arborescence.o'  Fichier
    15 : 'Dernier dossier'  Dossier
     
     
    Process returned 0 (0x0)   execution time : 0.372 s
    Press any key to continue.
    Exécution du code complet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    15 Fichiers
    1 : '1'  Dossier
    2 : '1.txt'  Fichier
     
    Process returned -1073741819 (0xC0000005)   execution time : 2.337 s
    Press any key to continue.

    Deuxième question, une fois que ça fonctionnera, je veux pouvoir lister les sous-dossiers en appelant récursivement la fonction, mais les noms de variables vont poser problème.. En effet, dans la deuxième instance de la fonction, des variables vont être crées alors qu'elles existent déjà.. Comment aborder ce problème ?

    Merci d'avance

  2. #2
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir,
    Il y a pas mal d’erreurs dans le code source la plus fragrantes est celle de la ligne ou vous copier le nom de l’élément et que vous l’ajouter dans la variable élément sans préalablement allouer de la mémoire pour pouvoir stocker l'information en clair vous tenter d’écrire à une adresse mémoire quelconque ce qui est très dangereux, car le comportement du résultat n’est pas déterminé, pire des cas votre système peut crasher.

    Un autre point il faut légèrement revoir la fonction qui renvoie un énumérateur en fonction du type du fichier serte ça semble logique, mais dans les faits tout est fichier même un répertoire, c’est juste qu’il est marqué comme étant un répertoire. Je vous conseille donc de bien distinguer les fichiers pour peu être dans un avenir proche ou autre savoir comment vous devez travailler avec le fichier. Voir une ancienne discussion pour plus de détail sur le sujet des fichiers
    À bientôt

  3. #3
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Mars 2017
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Mars 2017
    Messages : 59
    Par défaut
    merci à toi, j'ai rajouté un malloc à la ligne 74 (voir code du 1e message), de façon à stocker le nom dans un espace alloué (j'ai honte quand même..), mais j'ai toujours un crash (apres 3 lignes cette fois ci, ça progresse !)
    Une idée ?

    Je crois que je manque quand même de recule vis à vis de mon code, mais c'est pas évident..

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,
    La taille allouée ligne 74 n'est pas la bonne, il faut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                repertoireLu.elements[i] = malloc(strlen(fichierLu->d_name) + 1); // LIGNE AJOUTEE
    Pour gérer des appels récursifs, la fonction peut être appelée récursivement à condition de disposer d'une structure de résultat adéquate.
    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
    typedef struct Element
    {
        TYPE_FICHIER type; // FICHIER ou REPERTOIRE
        char*  nom;
        int    nombre_elements; // 0 si aucun ou FICHIER
        struct Element* elements; // NULL si aucun ou FICHIER
    } ELEM;
    ELEM* listerRepertoire( ELEM* pRepertoire ) {
        ....
        i++;
        ELEM* pElement = malloc( sizeof(ELEM) ); // ieme element trouvé
        pElement->type = estRepertoire(fichierLu->d_name);
        pElement->nom = malloc(strlen(fichierLu->d_name) + 1);
        strcpy( pElement->nom , fichierLu->d_name );
        pElement->nombre_elements = 0;
        pElement->elements = NULL;
        pRepertoire->elements[i] = pElement;
        if ( pElement->type == REPERTOIRE ) {
            listerRepertoire( element ); // appel recursif remplit element
        }
        ....
        return pRepertoire;
    }

Discussions similaires

  1. lister le contenu d'un dossier
    Par anthonycosson dans le forum Langage
    Réponses: 2
    Dernier message: 27/12/2007, 12h26
  2. lister le contenu d'un dossier avec ant
    Par slouma_b_h dans le forum ANT
    Réponses: 1
    Dernier message: 15/11/2007, 09h53
  3. Lister le contenu d'un dossier depuis une applet
    Par faocode dans le forum Applets
    Réponses: 1
    Dernier message: 11/05/2007, 10h05
  4. Lister le contenu d'un dossier
    Par WyLLoU dans le forum Access
    Réponses: 1
    Dernier message: 11/07/2006, 15h06
  5. Lister le contenu d'un dossier dans une ListBox
    Par zidenne dans le forum Langage
    Réponses: 2
    Dernier message: 25/10/2005, 12h51

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