Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1440 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C]readdir renvoi pas la bonne valeur

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C]readdir renvoi pas la bonne valeur

n°903498
Loizo
Posté le 20-11-2004 à 15:39:50  profilanswer
 

Bonjour, je débute en C et je bloque sur readdir. Je suis censé ouvrir un répertoire et liste son contenu mais ca ne marche pas. Je sais faut rechercher mais j'arrete pas et je trouve pas la solution a mon probleme...
 
Voici mon code (enfin la partie qui me saoule) :
 

Code :
  1. DIR *pdir = opendir(chemin);
  2.  if (pdir == NULL)
  3.  {
  4.   printf("erreur chemin \n" );
  5.   return -1;
  6.  }
  7.  struct dirent *fichier_lu = readdir(pdir);
  8.  printf("%s \n", fichier_lu->d_name);


 
Je travaille sous Linux.
Le probleme est que si je lance mon programme dans la console, par exemple :
./monProg /home/moi
 
printf("%s \n", fichier_lu->d_name); m'ecrit juste "." au lieu du nom d'un repertoire ou d'un fichier.
Ce qui fait que je ne peut pas avancer vu que tout ce que fait readdir c'est retourner "." :(
Merci a ceux qui pourront m'aider :jap:

mood
Publicité
Posté le 20-11-2004 à 15:39:50  profilanswer
 

n°903500
docmaboul
Posté le 20-11-2004 à 15:41:51  profilanswer
 

ben faut juste appeler readdir tant qu'elle ne retourne pas NULL.

n°903506
Loizo
Posté le 20-11-2004 à 15:51:53  profilanswer
 

Ouais d'accord mais normallement la variable d_name de la structure dirent retourne le nom du fichier pointé par readdir(). Or moi ca retourne toujours "." au lieu du nom donc  je ne peux pas étudier chaque fichier de mon répertoire ni descendre dans l'arborescence puisque je n'ai pas les bon noms...

n°903516
docmaboul
Posté le 20-11-2004 à 16:06:56  profilanswer
 

Loizo a écrit :

Ouais d'accord mais normallement la variable d_name de la structure dirent retourne le nom du fichier pointé par readdir(). Or moi ca retourne toujours "." au lieu du nom donc  je ne peux pas étudier chaque fichier de mon répertoire ni descendre dans l'arborescence puisque je n'ai pas les bon noms...


 
ben, c'est simple: ".", c'est le répertoire courant. Au prochain appel à readdir, vous obtiendrez un autre fichier/répertoire.

n°903521
Loizo
Posté le 20-11-2004 à 16:10:49  profilanswer
 

Bah apres au lieu de me retourner "." il me retourne ".."
Je sais que c'est le rep courant mais d'apres ce qu'on nous as expliqué en cours readdir ne fait ca.
Par exemple si dans mon home/moi j'ai :
home/moi/monFichier  
home/moi/unRep
 
readdir() va d'abord pointer sur monFichier et d_name vaudra "monFichier" et si je relance readdir() alors il pointera maintenant sur unRep et d_name vaudra "unRep" or moi pas du tout ca me retourne "." puis ".." puis "..." etc etc
Je vois pas du tout pourquoi :(:( Et ca m'empeche d'avancer vu que j'ai besoin du nom :(

n°903523
Lam's
Profil: bas.
Posté le 20-11-2004 à 16:15:47  profilanswer
 

Loizo a écrit :

Bah apres au lieu de me retourner "." il me retourne ".."
Je sais que c'est le rep courant mais d'apres ce qu'on nous as expliqué en cours readdir ne fait ca.
Par exemple si dans mon home/moi j'ai :
home/moi/monFichier  
home/moi/unRep
 
readdir() va d'abord pointer sur monFichier et d_name vaudra "monFichier" et si je relance readdir() alors il pointera maintenant sur unRep et d_name vaudra "unRep" or moi pas du tout ca me retourne "." puis ".." puis "..." etc etc
Je vois pas du tout pourquoi :(:( Et ca m'empeche d'avancer vu que j'ai besoin du nom :(


 
Arrete de déconner. readdir te renvoie '.' (répertoire en cours), puis "..", répertoire au dessus, puis tous les fichiers ou répertoires.  
D'ailleurs, "ls -al" sous Linux ou "DIR" sous DOS font la même chose.
La raison ? Te permettre de connaitre les droits et le possesseur du répertoire en cours et du répertoire au dessus.
 
Donc tu fais readdir jusqu'à ce que tu aies NULL. Et tu engueules ton prof parce qu'il a oublié de vous préciser ce comportement.


Message édité par Lam's le 20-11-2004 à 16:16:23
n°903524
Loizo
Posté le 20-11-2004 à 16:21:23  profilanswer
 

...
Ah... Ca fait pas du tout ce que je pensais alors :o
Pourtant dans notre feuille de TD c'est écrit :
"lecture de l'enregistrement suivant : readdir(...)"
Et d'apres les exemples qu'ils nous ont filé ca fonctionnaient comme je vous le disaient... Je capte pas comment avoir le nom de mon fichier alors... Je pensais que ct le but de readdir()
Merci en tout cas de vos réponses.
 
Edit :
Mais me suis peut etre mal exprimé :
struct dirent *fichier_lu = readdir(pdir);
printf("%s \n", fichier_lu->d_name);
Donc avec fichier_lu on ouvrir le repertoire pdir grace a readdir et ensuite avec fichier_lu.d_name on récupere le nom du répértoire ou fichier pointé par readdir.
C'est ca qu'on nous as expliqué en cours et je comprend donc pas pk fichier_lu->d_name renvoie "." puis ".." :(


Message édité par Loizo le 20-11-2004 à 16:25:42
n°903559
Sve@r
Posté le 20-11-2004 à 17:44:49  profilanswer
 

Loizo a écrit :

...
Edit :
Mais me suis peut etre mal exprimé :
struct dirent *fichier_lu = readdir(pdir);
printf("%s \n", fichier_lu->d_name);
Donc avec fichier_lu on ouvrir le repertoire pdir grace a readdir et ensuite avec fichier_lu.d_name on récupere le nom du répértoire ou fichier pointé par readdir.
C'est ca qu'on nous as expliqué en cours et je comprend donc pas pk fichier_lu->d_name renvoie "." puis ".." :(


Un répertoire contient plusieurs fichiers donc plusieurs noms donc tu es obligé de programmer une boucle puisque "readdir" ne lit qu'un seul nom à la fois!!!

Code :
  1. DIR *pdir;
  2. struct dirent *fichier_lu;
  3. pdir=opendir(chemin);
  4. if (pdir == NULL)
  5. {
  6.      perror("erreur chemin\n" );
  7.      return(-1);
  8. }
  9. while ((fichier_lu=readdir(pdir)) != NULL)
  10. {
  11.      printf("%s\n", fichier_lu->d_name);
  12. }


 
Par ailleurs, un répertoire contient en plus deux noms particuliers: "." qui est sa propre référence et ".." qui est la référence du répertoire du dessus donc "readdir" les liras eux-aussi.
Si ces noms ne t'interressent pas, tu dois vérifier ton nom !!!

Code :
  1. while ((fichier_lu=readdir(pdir)) != NULL)
  2. {
  3.      if (strcmp(fichier_lu->d_name, "." ) == 0 || strcmp(fichier_lu->d_name, ".." ) == 0)
  4.           continue;
  5.      printf("%s\n", fichier_lu->d_name);
  6. }



Message édité par Sve@r le 20-11-2004 à 17:50:10

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°903566
Loizo
Posté le 20-11-2004 à 17:56:56  profilanswer
 

Ok j'suis bien d'accord, je vais tester ca, sauf que  
(fichier_lu=readdir(pdir)) != NULL
 
me retourne ca quand je compile avec gcc :/
 
[cpp][/cpp]warning: assignment makes pointer from integer without a cast
/home/loizo/tmp/cc4DTAE8.o(.text+0x222): In function `chercheNom':
: undefined reference to `readir'
collect2: ld returned 1 exit status[cpp][/cpp]

n°903573
Taz
bisounours-codeur
Posté le 20-11-2004 à 18:07:16  profilanswer
 

readdir bachibouzouk
 
RTFM -> on a le nom correct de la fonction et son utilisation :o
 
 
if (strcmp(fichier_lu->d_name, "." ) == 0 || strcmp(fichier_lu->d_name, ".." ) == 0)
 
béni soit gcc qui optimise ce genre de chose, sinon on serait pas sorti

mood
Publicité
Posté le 20-11-2004 à 18:07:16  profilanswer
 

n°903574
matafan
Posté le 20-11-2004 à 18:07:24  profilanswer
 

A mon avis tu as oublié d'inclure dirent.h, ce qui fait que ton compilo suppose que readdir() renvoie un int, comme toute fonction non déclarée.


Message édité par matafan le 20-11-2004 à 18:08:07
n°903578
Taz
bisounours-codeur
Posté le 20-11-2004 à 18:18:17  profilanswer
 

matafan a écrit :

A mon avis tu as oublié d'inclure dirent.h, ce qui fait que ton compilo suppose que readdir() renvoie un int, comme toute fonction non déclarée.

besoin d'un opticien ?

n°903671
Loizo
Posté le 20-11-2004 à 20:12:26  profilanswer
 

Ah ben nan quand meme pas, j'ai pas oublié le dirent.h, et c'est la que je capte pas justement :o Voici tous mes includes :
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdbool.h>
 
Tu dis ca pour moi Taz ? Désolé mais bon on né par en connaissant par coeur toutes les subtilités de la prog systeme sous Unix :/ Et comme je trouve rien sur google qui réponde a mon probleme je me permet de demander ici...
 
 
Edit : pourtant dans le man de readdir ca dit :
VALEUR RENVOYÉE
readdir renvoie 1 s'il réussit, 0 en fin de répertoire, ou -1 s'il échoue, auquel cas errno contient le code d'erreur.    
 
Et pourtant dans tous les exemples que j'ai pu voir (net, mon cours et vous), faut tester NULL...


Message édité par Loizo le 20-11-2004 à 20:16:04
n°903674
Taz
bisounours-codeur
Posté le 20-11-2004 à 20:15:11  profilanswer
 

mais vous le faites exprès ou quoi ?
 
déjà compile en -Wall et recherche 'readir' dans ton source  
 
: undefined reference to `readir'
 
ça veut bien dire ce que ça veut dire. T'as vu ou une fonction readir toi ?
faut vraiment vous acheter des lunettes les gars ...

n°903675
blurk
Posté le 20-11-2004 à 20:16:05  profilanswer
 

Ce serait plus simple de dire qu'il manque un 'd'. ;)

n°903676
Loizo
Posté le 20-11-2004 à 20:17:08  profilanswer
 

Taz a écrit :

mais vous le faites exprès ou quoi ?
 
déjà compile en -Wall et recherche 'readir' dans ton source  
 
: undefined reference to `readir'
 
ça veut bien dire ce que ça veut dire. T'as vu ou une fonction readir toi ?
faut vraiment vous acheter des lunettes les gars ...


 
Oups :whistle:  
Bon je test, si c'est ca désolé parce que j'ai l'air con mais ca m'aide bien :)

n°903678
Loizo
Posté le 20-11-2004 à 20:18:28  profilanswer
 

blurk a écrit :

Ce serait plus simple de dire qu'il manque un 'd'. ;)


 
Clair mais bon au moins ca marche, ca me tue d'avoir bloqué comme ca pour rien... :/

n°903679
blurk
Posté le 20-11-2004 à 20:18:46  profilanswer
 

Et tu vois bien que readdir ne renvoie pas un entier, il renvoie un pointeur sur une structure...
 
Ma page de man dit ça :
 
VALEUR RENVOYÉE
       La fonction readdir() renvoie un pointeur sur une structure dirent,  ou
       NULL  lorsqu'une erreur se produit, ou lorsque la fin du répertoire est
       atteinte.

n°903683
Loizo
Posté le 20-11-2004 à 20:23:52  profilanswer
 

Ah ben c'est deja plus coherent.
Sur le net, ici par exemple (c la ou je regardais car j'ai pas le man en fr sur mon linux) ca parle d'un entier :/
http://linuxreviews.org/man/readdir/index.html.fr

n°903684
blurk
Posté le 20-11-2004 à 20:26:11  profilanswer
 

Ça c'est l'appel-système readdir ()... Je comprends que tu aies pu t'embrouiller... ;)
 
man 3 readdir pour avoir la bonne (les appels-système c'est la catégorie 2)


Message édité par blurk le 20-11-2004 à 20:28:17
n°903685
Loizo
Posté le 20-11-2004 à 20:28:38  profilanswer
 

Ah c'est pas pareil... Je savais pas :/
C'est bien compliqué tout ca... Bon je dois y aller, ma copine rale, merci pour votre aide en tout cas :jap:

n°903688
Taz
bisounours-codeur
Posté le 20-11-2004 à 20:42:45  profilanswer
 

paidai

n°903695
Loizo
Posté le 20-11-2004 à 20:50:43  profilanswer
 


 
lol faut dire que me regarder programmer c'est moyen :D

n°903774
Taz
bisounours-codeur
Posté le 20-11-2004 à 22:08:48  profilanswer
 

scandir powa de toutes façons

n°903789
Sve@r
Posté le 20-11-2004 à 23:04:02  profilanswer
 

Taz a écrit :

readdir bachibouzouk
 
if (strcmp(fichier_lu->d_name, "." ) == 0 || strcmp(fichier_lu->d_name, ".." ) == 0)
 
béni soit gcc qui optimise ce genre de chose, sinon on serait pas sorti


 
Hum... je vois pas trop comment faire mieux... :sarcastic:


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°903886
blurk
Posté le 21-11-2004 à 10:19:19  profilanswer
 

Il fait pas d'appels à strcmp et il utilise les instructions repz/cmpsb (avec les flags d'optimisaton -Ox)

n°903900
Loizo
Posté le 21-11-2004 à 11:12:49  profilanswer
 

Juste pour info, opendir ne lis pas les fichiers cachés c'est bien ca ?

n°903912
blurk
Posté le 21-11-2004 à 11:43:35  profilanswer
 

Il n'y a rien de ce genre de spécifié dans la page de manuel.

n°903920
Loizo
Posté le 21-11-2004 à 11:57:54  profilanswer
 

C'est bien ce que je vois mais bon c'est l'impression que ca me donne...

n°903921
blurk
Posté le 21-11-2004 à 12:06:26  profilanswer
 

Donne plus d'informations, il y a peut-être une erreur ailleurs, chez moi ça fonctionne comme il faut.

n°904025
Taz
bisounours-codeur
Posté le 21-11-2004 à 14:16:41  profilanswer
 

blurk a écrit :

Il fait pas d'appels à strcmp et il utilise les instructions repz/cmpsb (avec les flags d'optimisaton -Ox)

euh rien l'y oblige. il fait sa sauce comme il veut, au cas par cas

n°904030
Loizo
Posté le 21-11-2004 à 14:19:36  profilanswer
 

blurk a écrit :

Donne plus d'informations, il y a peut-être une erreur ailleurs, chez moi ça fonctionne comme il faut.


 
Bah j'essaye d'etudier ca se soir de mon coté et si vraiment je vois que j'y arrive pas je vous redemande :p

n°904096
blurk
Posté le 21-11-2004 à 14:39:20  profilanswer
 

Taz a écrit :

euh rien l'y oblige. il fait sa sauce comme il veut, au cas par cas


 
Oui, ben c'est ce qu'il fait dans ce cas :) Tu pensais à un autre moyen d'optimiser ?

n°904119
Taz
bisounours-codeur
Posté le 21-11-2004 à 14:51:52  profilanswer
 

chez pas, j'ai pas d'intel :o

n°904265
Loizo
Posté le 21-11-2004 à 20:02:22  profilanswer
 

blurk a écrit :

Donne plus d'informations, il y a peut-être une erreur ailleurs, chez moi ça fonctionne comme il faut.


 
Finalement j'ai réussis a faire fonctionner mon bordel par contre mon appel a stat renvoi tjs une erreur quand je parcours certains fichiers. Apres verification il s'avere que ce sont ces fichiers ci :
http://forum.hardware.fr/forum2.ph [...] 0&subcat=0
 
Donc j'essaye d'empecher mon programme de parcourir des liens (symbolique) mais a priori ca ne marche pas :
 

Code :
  1. if (S_ISDIR(bufchemin.st_mode))
  2. if (!S_ISLNK(bufchemin.st_mode))
  3.  //Appel récursif de ma fonction


 
J'ai essayé cet autre facon d'ecrire :

Code :
  1. if (bufchemin.st_mode & S_IFMT == S_IFLNK)


Ca ne parcours plus tout mes liens mais ca en parcours encore certain (je n'arrive pas a les differencier des autres)
 
ex :

Code :
  1. lrwxrwxrwx  1 loizo loizo      18 nov 21 19:01 lock -> 82.228.151.98:3112


n'est plus parcourus avec la 2nd méthode
 

Code :
  1. lrwxrwxrwx  1 loizo loizo   41 nov 16 18:47 a -> /usr/lib/jdk-1.4.1_01/jre/lib/i386/client


est parcouru quelque soit la facon dont je code le truc :/
 
C'est moi qui écrit mal le truc ou c'est ces liens qui sont bizzare et qu'il faut détécter autrement ?
 
Edit : D'un coté ca ne plante pas mon programme mais bon c'est pour savoir si c'est emmerdant et surtout je ne veux pas traverser les liens symbolique donc c'est surtout pour savoir si ma syntaxe est bonne...


Message édité par Loizo le 21-11-2004 à 20:05:08
n°904279
Sve@r
Posté le 21-11-2004 à 20:47:41  profilanswer
 

Loizo a écrit :

Finalement j'ai réussis a faire fonctionner mon bordel par contre mon appel a stat renvoi tjs une erreur quand je parcours certains fichiers. Apres verification il s'avere que ce sont ces fichiers ci :
http://forum.hardware.fr/forum2.ph [...] 0&subcat=0
 
Donc j'essaye d'empecher mon programme de parcourir des liens (symbolique) mais a priori ca ne marche pas :
 

Code :
  1. if (S_ISDIR(bufchemin.st_mode))
  2. if (!S_ISLNK(bufchemin.st_mode))
  3.  //Appel récursif de ma fonction


 
J'ai essayé cet autre facon d'ecrire :

Code :
  1. if (bufchemin.st_mode & S_IFMT == S_IFLNK)


Ca ne parcours plus tout mes liens mais ca en parcours encore certain (je n'arrive pas a les differencier des autres)
 
ex :

Code :
  1. lrwxrwxrwx  1 loizo loizo      18 nov 21 19:01 lock -> 82.228.151.98:3112


n'est plus parcourus avec la 2nd méthode
 

Code :
  1. lrwxrwxrwx  1 loizo loizo   41 nov 16 18:47 a -> /usr/lib/jdk-1.4.1_01/jre/lib/i386/client


est parcouru quelque soit la facon dont je code le truc :/
 
C'est moi qui écrit mal le truc ou c'est ces liens qui sont bizzare et qu'il faut détécter autrement ?
 
Edit : D'un coté ca ne plante pas mon programme mais bon c'est pour savoir si c'est emmerdant et surtout je ne veux pas traverser les liens symbolique donc c'est surtout pour savoir si ma syntaxe est bonne...


Déjà, tu devrais mettre des parenthèses histoire d'être sûr de tes opérations

Code :
  1. if ((bufchemin.st_mode & S_IFMT) == S_IFLNK)


 
Ensuite, essaye d'afficher avec un "printf" la valeur de ton "st_mode & S_IFMT" histoire de voir si ça vaut bien "S_IFLNK"
 
Enfin va faire un tour du coté de "man lstat" car, entre "stat" et "lstat" l'une des deux donne des informations sur le lien et l'autre donne des informations sur le fichier lié (mais jme souviens plus laquelle donne quoi)


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°904285
Loizo
Posté le 21-11-2004 à 21:10:05  profilanswer
 

Bah écoute en utilisant lstat tout marche niquel, j'ai du mal a capter pourquoi mais c'est l'essentiel :)
merci :jap:


Message édité par Loizo le 21-11-2004 à 21:10:35
n°904935
Sve@r
Posté le 22-11-2004 à 19:32:42  profilanswer
 

Loizo a écrit :

Bah écoute en utilisant lstat tout marche niquel, j'ai du mal a capter pourquoi mais c'est l'essentiel :)
merci :jap:


Paske l'une des deux fonctions te donne des infos sur le lien, et l'autre donne des infos sur le fichier qui y est lié.
Si tu utilises la mauvaise fonction sur un lien symbolique pointant sur un répertoire, tu récupères les infos du répertoire alors que tu veux récupérer les infos du lien !!!


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C]readdir renvoi pas la bonne valeur

 

Sujets relatifs
tester une valeur et imprimer[java] un random avec une valeur int
Liste menu (forumlaire), prob de transmission de valeurafficher la valeur d'un pointeur en ada
mettre la fenêtre IE à la bonne dimension[MySQL] valeur fixe dans requete de type select
IE ne prend pas en compte la valeur "height" d'un <td>Recherche la valeur de A quand la valeur B est maximale selon C
[FRAMESET] encore une bonne !PHP upload_max_filesize => modifier valeur par default
Plus de sujets relatifs à : [C]readdir renvoi pas la bonne valeur


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR