[C]readdir renvoi pas la bonne valeur

readdir renvoi pas la bonne valeur [C] - C - Programmation

Marsh Posté le 20-11-2004 à 15:39:50    

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:

Reply

Marsh Posté le 20-11-2004 à 15:39:50   

Reply

Marsh Posté le 20-11-2004 à 15:41:51    

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

Reply

Marsh Posté le 20-11-2004 à 15:51:53    

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...

Reply

Marsh Posté le 20-11-2004 à 16:06:56    

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.

Reply

Marsh Posté le 20-11-2004 à 16:10:49    

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 :(

Reply

Marsh Posté le 20-11-2004 à 16:15:47    

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
Reply

Marsh Posté le 20-11-2004 à 16:21:23    

...
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
Reply

Marsh Posté le 20-11-2004 à 17:44:49    

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.
Reply

Marsh Posté le 20-11-2004 à 17:56:56    

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]

Reply

Marsh Posté le 20-11-2004 à 18:07:16    

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

Reply

Marsh Posté le 20-11-2004 à 18:07:16   

Reply

Marsh Posté le 20-11-2004 à 18:07:24    

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
Reply

Marsh Posté le 20-11-2004 à 18:18:17    

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 ?

Reply

Marsh Posté le 20-11-2004 à 20:12:26    

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
Reply

Marsh Posté le 20-11-2004 à 20:15:11    

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 ...

Reply

Marsh Posté le 20-11-2004 à 20:16:05    

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

Reply

Marsh Posté le 20-11-2004 à 20:17:08    

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 :)

Reply

Marsh Posté le 20-11-2004 à 20:18:28    

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... :/

Reply

Marsh Posté le 20-11-2004 à 20:18:46    

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.

Reply

Marsh Posté le 20-11-2004 à 20:23:52    

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

Reply

Marsh Posté le 20-11-2004 à 20:26:11    

Ç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
Reply

Marsh Posté le 20-11-2004 à 20:28:38    

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:

Reply

Marsh Posté le 20-11-2004 à 20:42:45    

paidai

Reply

Marsh Posté le 20-11-2004 à 20:50:43    


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

Reply

Marsh Posté le 20-11-2004 à 22:08:48    

scandir powa de toutes façons

Reply

Marsh Posté le 20-11-2004 à 23:04:02    

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.
Reply

Marsh Posté le 21-11-2004 à 10:19:19    

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

Reply

Marsh Posté le 21-11-2004 à 11:12:49    

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

Reply

Marsh Posté le 21-11-2004 à 11:43:35    

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

Reply

Marsh Posté le 21-11-2004 à 11:57:54    

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

Reply

Marsh Posté le 21-11-2004 à 12:06:26    

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

Reply

Marsh Posté le 21-11-2004 à 14:16:41    

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

Reply

Marsh Posté le 21-11-2004 à 14:19:36    

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

Reply

Marsh Posté le 21-11-2004 à 14:39:20    

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 ?

Reply

Marsh Posté le 21-11-2004 à 14:51:52    

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

Reply

Marsh Posté le 21-11-2004 à 20:02:22    

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
Reply

Marsh Posté le 21-11-2004 à 20:47:41    

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.
Reply

Marsh Posté le 21-11-2004 à 21:10:05    

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
Reply

Marsh Posté le 22-11-2004 à 19:32:42    

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.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed