2017-05-07 3 views
-1

J'ai besoin de créer un programme qui fonctionne essentiellement de la même manière que l'utilitaire de liste sous Linux. J'ai essayé de faire fonctionner ça et je suis assez proche mais maintenant je me suis coincé. Essentiellement, il imprimera tous les fichiers et sous-répertoires qui sont contenus avec un répertoire (c'est-à-dire si je cours ./project3, il énumère whatevers dans ce répertoire). Cependant, une fois que j'essaie d'obtenir l'appel récursif de travail, il recrache quelque chose comme:Programme pour imprimer les répertoires en utilisant c ne fonctionne pas, problèmes avec l'appel récursive

sh: 1: /home/RageKage/Documents/Project3/dir1: Permission denied 

C'est là que je suis coincé, je ne sais pas exactement ce qu'il faut faire d'ici. J'obtiens le chemin du répertoire à explorer en utilisant realpath et ça marche bien, mais l'appel récursif ne fonctionne tout simplement pas et je ne suis pas vraiment sûr de ce que je fais de mal. Toute aide serait appréciée car je suis relativement nouveau à ce sujet.

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <dirent.h> 
#include <string.h> 
#include <limits.h> 

int main (int argc, char *argv[]) 
{ 
    DIR *dir; 
    struct dirent *sd; 
    const char *direct; 
    char buf[PATH_MAX + 1]; 

    if (argc < 2) 
    { 
     direct = "."; 
    }else{ 
     direct = argv[1]; 
     //printf("Hey this is argv[1]: %s\n", argv[1]); 
    } 


    dir = opendir(direct); 

    if (dir == NULL) 
    { 
     printf("ERROR! NO DIRECTORY TO OPEN!\n"); 
     exit(1); 
    } 

    while((sd=readdir(dir)) != NULL) 
    { 

     if (!strcmp(sd->d_name, ".") || !strcmp(sd->d_name, "..")) 
     { 

     }else{ 
      printf("\n>> %s\n", sd->d_name); 
     } 


     if (!strcmp(sd->d_name, "..") || !strcmp(sd->d_name, ".")) 
     { 

     }else if (sd->d_type == 4){ 
      printf("Attempting to Run!\n"); 

      realpath(sd->d_name, buf); 
      printf("[%s]\n", buf); 

      system(("./project3 %s", buf)); 
      printf("\n"); 

     } 

    } 


    closedir(dir); 

    return 0; 
} 
+2

Où est la récursivité? – melpomene

+0

'' 'realpath (sd-> d_name, buf); système (buf); Buf contient le vrai chemin vers le répertoire plus je crois que la commande utilisée pour démarrer le programme, quelque chose comme ./project3/home/RageKageDocuments/Project3/dir3. Au moins c'est ce que je reçois quand j'imprime buf. – RageKage

+0

Vraiment? Quelle est la sortie exacte que vous obtenez lorsque vous exécutez ce programme? – melpomene

Répondre

0
system(("./project3 %s", buf)); 

Vous appelez récursive le programme lui-même à nouveau? Cela semble un peu inefficace, et difficile à faire puisque vous devez savoir où se trouve le fichier exécutable. En général, il pourrait être à peu près n'importe où (à partir de /bin, /usr/bin etc.), et tout ce que vous êtes susceptible d'obtenir dans argv[0] est la partie du nom de fichier, pas tout le chemin.

En outre, comme on dit dans les commentaires, func((this, that)) est le même que func(that), pas func(this, that), depuis la parenthèse faire l'acte de la virgule comme l'opérateur virgule, et non comme un séparateur d'argument. Et system() prend seulement un argument de toute façon, donc vous devrez utiliser sprintf() pour construire la ligne de commande. (Ou peut-être utiliser pour donner réellement les exec() fonctions arguments séparés sans invoquer un shell, mais vous devez faire le fork(), aussi.)

Je vous suggère de déchirage cette idée, et de mettre la navigation dans l'arborescence des répertoires en fonction de son propre, et appelant que récursive:

void walkpath(void) 
{ 
    DIR *dir = opendir("."); 
    struct dirent *sd; 
    while((sd = readdir(dir)) != NULL) { 
     /* ... */ 
     if (sd->d_type == DT_DIR) { 
      chdir(sd->d_name); 
      walkpath(); 
      chdir(".."); 
     } 
    } 
} 
int main(...) 
{ 
    /* ... */ 
    chdir(directory); 
    walkpath(); 
} 

J'utilisé chdir ici pour changer le répertoire de travail du processus ainsi que la promenade. Si vous devez suivre le nom complet du répertoire, vous devez l'ajouter. En outre, maintenant vous avez le test pour . et .. deux fois. Utilisez continue pour terminer cette itération de la boucle afin de ne plus avoir à tester la même chose.

if (strcmp(sd->d_name, ".") == 0 || strcmp(sd->d_name, "..") == 0) { 
    continue; 
} 
+0

Cela a aidé une tonne! L'appel récursif du programme a causé une tonne de problèmes, j'ai donc fait ce que vous avez suggéré et divisé le programme. Je l'ai écrit différemment de ce que vous avez posté mais le résultat final était le même. Merci beaucoup! – RageKage