2010-08-21 15 views
1

Le programme consiste à ouvrir un répertoire et à afficher le nom des fichiers ... c'est-à-dire s'il y a un fichier ... il faut dire FICHIER .... sinon RÉPERTOIRE .. mais le programme affiche tous les fichiers comme répertoire ..Accéder aux répertoires dans C

quelqu'un pourrait-il pls vérifier le code pour toutes les erreurs .... thnx

#include<stdio.h> 
#include<dirent.h> 
#define DIR_path "root/test"  
main() 
{ 
    DIR *dir; 
    dir=opendir(DIR_PATH); 
    printf("THe files inside the directory :: \n"); 

    struct dirent *dent; 
    if(dir!=NULL) 
    { 

     while((dent=readdir(dir))) 
     { 
      FILE *ptr; 
      printf(dent->d_name); 

       if(ptr=fopen(dent->d_name,"r")) 
       { 
        print("\tFILE\n"); 
        fclose(ptr); 
       } 
       else 
        printf("\t DIRECTORY\n"); 
     } 
      close(dir); 
    } 
    else 
      printf("ERROR OPENIN DIRECTORY"); 

} 
+1

possible de duper http://stackoverflow.com/questions/1542763/what-is-the-correct-way-to-use-the-stat-function-to-test-if-a-dirent -is-a-direc, http://stackoverflow.com/questions/3029633/how-to-use-dirent-h-correctly, et/ou http://stackoverflow.com/questions/1271064/how-do- i-loop-through-tous-fichiers-dans-un-dossier-using-c. En passant, c'est l'utilisation la plus laide que j'ai jamais vue. Voir les liens pour la raison pourquoi. – rubenvb

Répondre

9

un problème est qu'un répertoire est également un type de fichier, et peut être normalement fopen() éd. Vous voulez appeler lstat() sur chaque fichier pour vérifier s'il s'agit d'un répertoire. Comme ceci:

struct stat st; 
lstat(dent->d_name, &st); 
if(S_ISDIR(st.st_mode)) 
    printf("\t DIRECTORY\n"); 
else 
    printf("\t FILE\n"); 

Mais cette erreur devrait conduire à ce que toutes les entrées soient affichées en tant que fichiers. Avez-vous des autorisations de lecture sur les fichiers de ce répertoire? Quelle est la valeur de errno après l'appel fopen()?

+0

En fait, vous voudrez probablement vérifier le code retour de ** lstat() ** pour les erreurs. Dans une boucle * readdir() *, c'est peu probable, mais possible. – NVRAM

0

Supposons que root/test contient un fichier appelé foo. L'appel à dent=readdir(dir) définit dent->d_name à "foo". Vous avez déjà une sortie de débogage qui montre ceci: printf(dent->d_name) ¹. Ensuite, vous essayez d'ouvrir foo avec fopen, mais le fichier est en réalité root/test/foo. Donc, ceci échoue à chaque fois (sauf si vous avez aussi un fichier appelé foo dans le répertoire courant).

Il y a deux façons d'ouvrir le fichier: droit

  • construire le nom complet du fichier en concaténant l'argument opendir avec le nom du fichier. Quelque chose comme:

    /*before */ 
    size_t dir_length = strlen(DIR_PATH); 
    char *filename = malloc(dir_length + NAME_MAX + 2); /*error checking omitted*/ 
    strcpy(filename, DIR_PATH); 
    filename[dir_length] = '/'; 
    filename[dir_length+1] = 0; 
    while ((dent = readdir(dir)) != NULL) { 
        strcpy(filename + dir_length + 1, dent->d_name); 
        /*now call lstat, fopen, etc. on filename*/ 
    
  • changement dans le répertoire que vous listez. Par exemple, changer l'appel à opendir

    chdir(DIR_PATH); /*error checking omitted*/ 
    dir = opendir("."); 
    

    Vous devez vous rappeler d'enregistrer le répertoire précédent avec getcwd et chdir revenir plus tard. Cette méthode n'est pas recommandée dans les logiciels de production car il est possible d'avoir un répertoire en cours que vous ne pouvez pas chdir en raison d'autorisations.

slacker has already explained why fopen can't be used to test if a file is a directory.

¹ qui, par la voie devrait être puts(dent->d_name) ou mieux encore fputs(dent->d_name, stderr): votre appel printf d'origine briserait si un nom de fichier contient %, ce qui est un gros problème pour la sortie de débogage, mais est une mauvaise habitude à prendre.

0

sa combinaison des deux réponses par fainéant et Gilles. utilisez lstat mais ne l'utilisez pas comme slacker dit. Vous devez envoyer à lstat le chemin complet, pas seulement dent-> d_name. Et si vous le savez lstat vous devez inclure sys/stat.h>
si vous regardez la page de manuel pour lstat il existe un programme de test en bas ou tout simplement regarder le mien.

Voici mon programme qui tente de mimer « ls » sur linux.Remarque: les couleurs des séquences d'échappement ne fonctionnent pas dans les fenêtres au cas où vous vous inquiéteriez de la portabilité.

#include <iostream> 
#include <dirent.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 

int main(int argc,char* argv[]){ 
char blue[] = { 0x1b, '[', '1', ';', '3', '4', 'm', 0 }; 
char normal[]={ 0x1b, '[', '0', ';', '3', '9', 'm', 0 }; 
char green[]= { 0x1b, '[', '0', ';', '3', '2', 'm', 0 }; 
char red[]= { 0x1b, '[', '0', ';', '3', '1', 'm', 0 }; 
char cyan[]= { 0x1b, '[', '0', ';', '3', '6', 'm', 0 }; 
DIR* myDirectory; 
char *path=NULL; 
size_t size=100; 
int result; 
char* fullpath; 
if (argc >=3){ 
    std::cout<<"Usage: myls <path>"<<std::endl; 
    return -1; 
} 
if (argc >= 2){ 
    myDirectory=opendir(argv[1]); 
    if (errno==ENOENT){ 
    std::cout<<"error: file does not exist"<<std::endl; 
    return -1; 
    } 
    path=argv[1]; 
if (path[strlen(path)-1]!='/') 
strcat(path,"/"); 
} 
else if(argc==1){ 
    path=getcwd(path,size); 
    strcat(path,"/"); 
    myDirectory=opendir(path); 
} 
struct stat fileProperties; 
struct dirent* directory; 
do{ 
    directory=readdir(myDirectory); 
    if (directory!=NULL){ 
    fullpath=new char[strlen(path)+strlen(directory->d_name)+2]; 
    strcat(fullpath,path); 
    strcat(fullpath,directory->d_name); 
    result=lstat(fullpath,&fileProperties); 
    //std::cout<<result<<fullpath; 
    switch (fileProperties.st_mode & S_IFMT){ 
     case S_IFDIR: std::cout<<blue; 
      break; 
     case S_IFLNK: std::cout<<cyan; break; 
     case S_IFREG: std::cout<<normal; 
     default: std::cout<<normal; 
     if (fileProperties.st_mode & S_IXUSR) 
      std::cout<<green; 
     break; 
     } 

     std::cout<<directory->d_name<<"\n"; 
     std::cout<<normal; 
    } 
    }while(directory!=NULL); 
    std::cout<<normal<<'\n'; 
    closedir(myDirectory); 
    delete[] fullpath; 
    return 0; 
}