2016-06-20 158 views
1

我一直在嘗試在C上實現類似ls -R的問題,事情是我需要列表遞歸列出從給定目錄開始的所有內容,然後用列表中的那些常規文件進行操作。 這是我到目前爲止有:遞歸列表

void ls(char* path){ 
    DIR *directory; 
    struct dirent *filei; 
    struct stat stats; 
    directory = opendir(path); 
    if (directory != NULL) 
    { 
     while ((filei=readdir(directory))!=NULL){ 
      stat(filei->d_name, &stats);  
      printf(" %s\n", filei->d_name); 
      if (S_ISDIR(stats.st_mode)){ 
       char *buf = malloc(strlen(path)+strlen(filei->d_name)+2); 
       strcpy(buf,path); 
       strcat(buf,"/"); 
       strcat(buf,filei->d_name); 
       ls(buf); 
      } 
     } 
     closedir(directory); 
    } 
    else{ 
     printf("Error.\n");  
    } 
} 

它不會在所有的工作,它表明,甚至在文件夾我的工作而不是文件。 有什麼想法? 謝謝。

+1

這是使用文件/目錄操作時的常見問題。 'd_name'不是一個完整的路徑。所以除非你當前的目錄是包含那個文件/目錄的目錄,否則你不能「統計」它。 'opendir'不會改變你的當前目錄。調用'stat'之前需要調用'chdir'。或者構建完整的路徑名稱。 – kaylum

+1

您還需要過濾'.'和'..'條目。否則,您將以infinete遞歸結束。 – kaylum

+0

這解決了無限遞歸問題,但我不能讓它工作,是不是我建立了完整的路徑已經與此? 'char * buf = malloc(strlen(path)+ strlen(filei-> d_name)+2);' 'strcpy(buf,path);' 'strcat(buf,「/」);' 'strcat (buf,filei-> d_name);' – Stieg

回答

1

代碼的下面返工完整的文件路徑上呼籲stat(),跳過了和「..」目錄,修復了內存泄漏,並增加只是淡淡的錯誤處理:

#define SEPARATOR "/" 

void ls(const char *path) 
{ 
    DIR *directory = opendir(path); 

    if (directory != NULL) 
    { 
     struct dirent *filei; 

     while ((filei = readdir(directory)) != NULL) 
     { 
      if (strcmp(filei->d_name, ".") == 0 || strcmp(filei->d_name, "..") == 0) 
      { 
       continue; 
      } 

      char *buffer = malloc(strlen(path) + strlen(filei->d_name) + strlen(SEPARATOR) + 1); 
      strcat(strcat(strcpy(buffer, path), SEPARATOR), filei->d_name); 

      struct stat stat_buffer; 

      if (stat(buffer, &stat_buffer) == 0) 
      { 
       printf("%s\n", buffer); 

       if (S_ISDIR(stat_buffer.st_mode)) 
       { 
        ls(buffer); 
       } 
      } 
      else 
      { 
       perror(NULL); 
      } 

      free(buffer); 
     } 

     closedir(directory); 
    } 
    else 
    { 
     perror(NULL);  
    } 
} 

看看它是否適合你更好。

3

您不能遞歸到「。」和「..」條目。至少無限地遞歸到相同的目錄或嚴重地去向上。過濾器:

if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) ls(buf); 

您還必須stat到的完整路徑:「」

char *buf = malloc(strlen(path)+strlen(filei->d_name)+2); 
strcpy(buf,path); 
strcat(buf,"/"); 
strcat(buf,filei->d_name); 
stat(buf, &stats); 
if (S_ISDIR(stats.st_mode)) { 
    if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) { 
    ls(buf); 
    } 
}