2017-05-07 27 views
-1

我需要創建一個程序,基本上行爲類似於Linux上的列表實用程序。我一直試圖讓這個工作,我非常接近,但現在我已經卡住了。從本質上講,它將打印包含在目錄中的任何文件和子目錄(即,如果我運行./project3,它會在該目錄中列出凡是)。但是,一旦我試圖讓遞歸調用工作就吐出這樣的:程序打印目錄使用c不工作,問題與遞歸調用

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

這就是我堅持,我不完全知道該怎麼在這裏做。我得到了使用實時路徑探索目錄的路徑,這工作正常,但遞歸調用不起作用,我不完全確定我做錯了什麼。任何幫助將不勝感激,因爲我相對較新。

#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

哪裏是遞歸? – melpomene

+0

'''realpath(sd-> d_name,buf); system(buf); 012f''' buf包含目錄的真實路徑加上我相信用來啓動程序的命令,所以類似./project3/home/RageKageDocuments/Project3/dir3。至少這就是我打印buf時得到的結果。 – RageKage

+0

真的嗎?運行此程序時獲得的確切輸出是什麼? – melpomene

回答

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

你遞歸調用程序本身來着?這聽起來有點低效,而且很難做到,因爲你需要知道可執行文件的位置。一般來說,它可能在任何地方(從/bin,/usr/bin等開始),並且您可能在argv[0]中獲得的所有內容都是文件名部分,而不是整個路徑。

此外,如在評論中說,func((this, that))相同func(that),不func(this, that),因爲括號使逗號充當逗號操作符,而不是作爲一個參數的分隔符。而system()無論如何只需要一個參數,所以你需要使用sprintf()來構建命令行。 (或者可能使用exec()函數實際上給出單獨的參數而不調用shell,但是您也需要執行fork()。)

我建議廢除該想法,並將目錄樹放入函數它自己的,並調用遞歸:

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(); 
} 

我以前chdir這裏與步行沿改變進程的工作目錄。如果您需要跟蹤完整的目錄名稱,那麼您需要添加該目錄。

另外,現在您有兩次測試...。使用continue來終止循環的迭代,所以你不需要再次測試同樣的事情。

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

這幫了大忙!再次遞歸調用程序導致了大量問題,所以我按照您的建議做了分割並將程序分開。我寫的與你發佈的內容不同,但最終的結果是一樣的。非常感謝! – RageKage