2016-06-20 2 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'은 전체 경로가 아닙니다. 따라서 현재 디렉토리가 그 파일/디렉토리를 포함하지 않는 한'stat' 할 수 없습니다. 'opendir'은 현재 디렉토리를 변경하지 않습니다. 'stat'를 호출하기 전에'chdir'을 호출해야합니다. 또는 전체 경로 이름을 구성하십시오. – kaylum

+1

또한'.' 및'..' 항목을 필터링해야합니다. 그렇지 않으면 infinete 재귀로 끝날 것입니다. – kaylum

+0

이것은 무한 재귀 문제를 해결하지만 아직 작동하지 못합니다. 이미이 전체 경로를 구성하고 있지 않습니까? strcat (buf, path); strcat (buf, "/");' 'strcat (buf, path); (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

"." 및 ".."항목. 같은 방향으로 적어도 무한정 재발행하거나 까지 올리십시오. 필터 : 또한 반드시 전체 경로 상에 stat

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

: "."

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