2014-09-13 94 views
0

我想動態地填充指定目錄路徑內的文件名和目錄名的字符串數組。C - 目錄探索

根據你的說法,這是這個目的的最快實現嗎?

如果不是,你可以建議一個替代實施?

int exploreDirectory(const char *dirpath, char ***list, int *numItems) { 
    DIR *dirstream = NULL; 
    struct dirent *direntp = NULL; 
    size_t listSize = 5; 

    errno = 0; 
    if (!(dirstream = opendir(dirpath))) 
     return errno;  

    if (!((*list) = malloc(sizeof(char *) * listSize))) { 
     fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath); 
     exit(EXIT_FAILURE); 
    } 

    *numItems = 0; 

    while(1) { 
     errno = 0; 
     if (!(direntp = readdir(dirstream))) 
      break; 
     if (*numItems + 1 == listSize) { 
      listSize *= 2;   
      if (!((*list) = realloc((*list), sizeof(char *) * listSize))) { 
       fprintf(stderr, "Error in list reallocation for file list: dirpath=%s.\n", dirpath); 
       exit(EXIT_FAILURE); 
      } 
     } 
     *numItems += 1;  
     (*list)[*numItems - 1] = stringDuplication(direntp->d_name);  
    } 

    if (errno != 0) { 
     fprintf(stderr, "Error in readdir for file list: dirpath=%s.\n", dirpath); 
     exit(EXIT_FAILURE); 
    } 

    if (closedir(dirstream) == -1) { 
     fprintf(stderr, "Error in closedir for file list: dirpath=%s.\n", dirpath); 
     exit(EXIT_FAILURE); 
    } 

    free(direntp); 

    return 0; 
} 
+0

ftw()和nftw()是爲了做一個文件樹遍歷,降序目錄。 find命令基於nftw()。 scandir()讀取一個目錄的內容。我不完全確定其中哪些滿足您的需求,但是他們是按照您已經非常有效地編碼的。 – 2014-09-13 14:04:45

+0

感謝您對scandir的建議! ;-)更改實施:現在基於scandir! – 2014-09-13 14:44:19

+0

成語'指針= realloc(指針,大小)'是一個等待發生的內存泄漏。如果'realloc()'失敗,它將引用前面分配的內存。使用'char ** newlist = realloc((* list),sizeof(* list)* listSize);'並在分配給'* list'之前檢查'newlist!= 0'。 – 2014-09-13 15:00:20

回答

0

這是基於scandir的實現!

int exploreDirectory(const char *dirpath, char ***list, int *numItems) { 
    struct dirent **direntList; 
    int i; 
    errno = 0; 

    if ((*numItems = scandir(dirpath, &direntList, NULL, alphasort)) == -1) 
     return errno; 

    if (!((*list) = malloc(sizeof(char *) * (*numItems)))) { 
     fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath); 
     exit(EXIT_FAILURE); 
    } 

    for (i = 0; i < *numItems; i++) { 
     (*list)[i] = stringDuplication(direntList[i]->d_name); 
    } 

    for (i = 0; i < *numItems; i++) { 
     free(direntList[i]); 
    } 

    free(direntList); 

    return 0; 
}