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 :

Connaître le contenu d'un dossier


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut Connaître le contenu d'un dossier
    Bonjour à tous!

    J'ai un programme en C qui permet de faire une acquisition vidéo issue d'une WebCam.

    Je suis sous Linux, les webcam détectées sont placées dans le répertoire /dev/, sous la forme video0, video1 etc...

    JE voudrais que mon programme, lors de son lancement détecte le nombre de caméras connectées, les liste, puis ensuite active chacune d'elle.

    Ma question est simple: comment faire pour accéder au contenu du dossier /dev, et mettre son contenu, par exemple, sous forme de tableau pour pouvoir ensuite l'exploiter ultérieurement?

    Merci d'avance pour vos réponses expertes,
    Bonne aprem
    F

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Flophx
    Ma question est simple: comment faire pour accéder au contenu du dossier /dev, et mettre son contenu, par exemple, sous forme de tableau pour pouvoir ensuite l'exploiter ultérieurement?
    <dirent.h>, opendir(), readdir() ... C'est pas une FAQ ?
    C'est pas standard C, mais c'est POSIX.1, donc très portable.

  3. #3
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    J'ai utilisé ces fonctions, mais je me retrouve avec une erreur de segmentation lorsque je fais deux appels à ma fonction:

    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
     
    void listingDossier(const char ** tableau,const char* dossier, const char *element, size_t nombre){
     
    	struct dirent *lecture;
    	DIR *rep;
    	rep = opendir(dossier);
    	size_t nb = nombre;
    	int i=0;
     
    		while ((lecture = readdir(rep)))
    		{
    			char * nomComplet;
    			const char * nom = lecture->d_name;
     
    			if(strncmp(nom, element, nb)==0){
    				sprintf(nomComplet, "%s%s",dossier,nom);
    				tableau[i]=nomComplet;
    				printf("FICHIER%d: %s\n",i,tableau[i]);
    				i++;
    			}
     
    		}
    	closedir(rep);
    }
    avec les appels suivants:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    listingDossier(&repertoireVideo,"/dev/","video",5);
    //printf("Repertoire video 0: %s\n", repertoireVideo[0]);
    listingDossier(&repertoireMnt,"/mnt/","",0);
    J'ai aussi une erreur de segmetation lorsque je fais un printf sur un des éléments de repertoireVideo, qui est déclaré comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const char*repertoireVideo;
    const char*repertoireMnt;
    J'ai nécessairement fait une erreur, mais où?
    Merci à ceux qui pourront m'éclairer

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    ta variable nom_complet n'est pas allouée, et tu fais un sprintf....

  5. #5
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    non!!!
    Je me suis mal exprimé , le printf dans la fonction marche parfaitement!!
    C'est celui qui est en commentaire entre les deux appels à la fonciton qui fait une erreur de segmentation!!

    Et le fait qu'il y ait une erreur lors du second appel!

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    je répète, ta varaible nom_complet n'est pas allouée, tu lui fais un sprintf dedans, et ça va écraser n'importe quoi....

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    et en plus tu mets un '=' pour copier une chaine, ...

    Révises tes cours :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    			if(strncmp(nom, element, nb)==0){
                            nomComplet = malloc ( (strlen(dossier)+strlen(nom)+2) );                                              
                            if ( nomComplet != NULL )
                               { 
    	                    sprintf(nomComplet, "%s/%s",dossier,nom);
                                strcpy (tableau[i],nomComplet);
    Si tableau[i] est dimensionné, bien entendu, ET en N lignes, ET en M caractères par lignes....

  8. #8
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Je comprends pas bien la remarque, car ce qui est contenu dans nom complet et affiché par le printf correspond bien à ce que je cherche... Pourrais tu être plus explicite?

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    tu n'as pas alloué la place pour stocker une chaîne dans nomComplet, tu as juste déclaré un pointeur...

    Donc quand tu fais un sprintf, ça va écrire n'importe où dans la mémoire, par exemple dans du code.....

    Ensuite, tu as mis "tab[i] = nomComplet", ce qui ne fait de copie de chaine....

    Voir mon exemple ci dessus....

  10. #10
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    le tableau n'est pas de taille connue, car a priori on ne sait pas combien il y a de caméras connectées(/dev/) et combien de périphérques sont montés (/mnt/)

    Sinon j'avais pas vu le bout de code explicatif, donc ma réponse fut rapide, je vais tester ca

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    si il est pas de taille connue, tu devrais soit faire une liste chaînée, soit tu n'as pas besoin de nomComplet (variable locale), mais alors tu dois :
    1) réallouer tab pour ajouter un élément
    2) tester si l'allocation a marché
    3) si ça a marche, faire l'allocation mise pour nomComplet sur tab[i]
    4) tester si ça a marché
    5) si ça a marché :
    -copier la chaine
    -incrémenter le nombre de lignes
    6) si une des allocations a pas marché, sortir un code d'erreur.

  12. #12
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    nomComplet est juste une variable locale, mais simplement j'ai besoin de comprendre pourquoi lors que je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    tableau[i]=nomComplet;
    printf("FICHIER%d: %s\n",i,tableau[i]);
    Je trouve bien ce qui est connecté? Ca veut dire que ca le fait "localement", dans la variable tableau, mais que ce qu eje désire modifier (repertoireVideo), n'est pas pris en compte. J'ai bien totu saisi?

  13. #13
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Bien, j'ai fait cela:

    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
     
    while ((lecture = readdir(rep)))
    		{
    			char * nomComplet;
    			const char * nom = lecture->d_name;
     
    			if(strncmp(nom, element, nb)==0){
    				nomComplet=malloc((strlen(dossier)+strlen(nom)+2));
     
    					if(nomComplet!=NULL){
    						sprintf(nomComplet, "%s%s",dossier,nom);
    						tableau[i]=malloc((strlen(nomComplet)+2));
    						strcpy(tableau[i],nomComplet);
    						printf("FICHIER%d: %s\n",i,tableau[i]);
    						free(nomComplet);
    						free(tableau[i]);
    						i++;
    					}
     
    			}
     
    		}
    Mais je me heurte aux problèpmes suivants:

    1/ Sur mes deux appels à la fonction, seul celui sur "/mnt/" fonctionne. L'autre s'exécute, mais ne me donne aucun résultat;

    2/ J'ai toujours une erreur de segmentation lorsque j'essaie d'accéder au contenu de repertoireMnt ou repertoireVideo

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    c'est sûr, tu libères tableau[i].......

    Que tu fasses un free(nomComplet), c'est bien, pusique c'et unevraraible intermédiaire.

    Mais tableau[i] doit ressortir, donc surtout pas de free à ce niveau là...

    Uniquement quand tu n'auras plus besoin de tableau....


    Et tu ne testes pas si le retour de l'alloc. de tableau[i] s'est bien passée..

  15. #15
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Bien, j'ai modifier mon code:

    1/ j'ai rajouté le test sur l'alloc n°2
    2/ j'ai enlevé le free() de trop
    3/ j'avais débranché la cam, pas étonnant que le premier appel ne marchait pas

    MAIS, j'ai toujours mon erreur de segmentation lorsque j'essaie d'afficher le contenu de mon repertoireVideo ou repertoireMnt....

  16. #16
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    je pense qu'à ce niveau là, faudrait voir cette routine et celle qui l'appelle.... Peut-être un problème de stockage ou de reinit de tableau...

  17. #17
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Personne ne peut faire une compilation et une exécution de mon code, car il est compilable. En effet le main ne contient que:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    listingDossier(&repertoireVideo,"/dev/","video",5);
    printf("Repertoire video 0: %s\n", repertoireVideo[0]);
    listingDossier(&repertoireMnt,"/mnt/","",0);
    et il y a un main.h qui contient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const char*repertoireVideo;
    const char*repertoireMnt;
    et évidemment les include# qui vont bien....

  18. #18
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    ouaias c'est bien ce que je pensais...

    Tes tableaux sont pas alloués... i n'est pas initialisé, et ton pointeur en entrée sur tableau n'est pas du bon type (et en plus const, donc tu peux pas le modifier).

    OK...

    Si tu veux vraiment que ce soit soupleet dynamique, voici :

    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
     
    void listingDossier(char *** tableau,const char* dossier, const char *element, size_t *nombre){
    int i = 0 ;
    ..........
     
    while ((lecture = readdir(rep)) != NULL )
     {
        char * nomComplet = NULL ;
        const char * nom = lecture->d_name;
        char **tmp = NULL ;
     
       if(nomComplet!=NULL){
               sprintf(nomComplet, "%s%s",dossier,nom);
               tmp = (char **) realloc ( tableau, (i+1)*sizeof(char*)) ;
               if ( tmp != NULL )
                 {   
                     *tableau = tmp ;
     
    	         (*tableau)[i]=malloc((strlen(nomComplet)+2));
                     if ( (*tableau)[i] != NULL )
                       {
    	            strcpy((*tableau)[i],nomComplet);
    	            printf("FICHIER%d: %s\n",i,(*tableau)[i]);
                        i = i++ ;
                       }
                 }
              free(nomComplet);
          }
     
        *nombre = i ;
    }
    Grâce au realloc, tu alloues la place pour chaque élément du listing.
    Grâce au tmp, tu t'assures que si ça échoue, tu gardes ton pointeur pour pouvoir le libérer.
    Grâce au *** dans le passage de paramètre, tu t'assures que la routine appelante est au courant que la valeur du pointeur à changer
    Grâce à *nombre, tu t'assures que tu as ien le nombre effectifs d'éléments.

    Donc l'appel se fera par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    listingDossier(&repertoireVideo,"/dev/","video", &nfichiersvideo);

  19. #19
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    J'ai une erreur de compilation, il apprécie pas des masses le "&repertoireVideo" combiné avec le "char ***tableau"....

  20. #20
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    ben faut être cohérent...

    Tu passes un répértoire déclaré char *, mais dans la routine tu l'appelles tableau.
    Si c'est un tableau, il doit être déclaré char **.

    C'est un tableau de chaînes, qui sera alloué dynamqiquement, donc un pointeur de pointeur ....

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 17/01/2006, 14h50
  2. ajouter le contenu d'un dossier ftp à une bdd
    Par lioudow dans le forum Requêtes
    Réponses: 2
    Dernier message: 16/11/2005, 19h46
  3. Lister le contenu d'un dossier dans une ListBox
    Par zidenne dans le forum Langage
    Réponses: 2
    Dernier message: 25/10/2005, 12h51
  4. [OmniMark 5] Copier contenu d'un dossier dans autre dossier
    Par Hoegaarden dans le forum Autres langages
    Réponses: 3
    Dernier message: 24/08/2005, 16h59
  5. afficher le contenu d'un dossier distant
    Par roots_man dans le forum ASP
    Réponses: 3
    Dernier message: 04/02/2005, 17h23

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