2012-06-19 116 views
0

我想创建一个方法来读取一个目录,并在数据结构中查找并保存所有包含的目录以及每个目录的所有子目录。具体来说,我想的名字被引用为:在C++中通过递归查找目录和子目录

文件夹1 folder11 folder12 文件夹2 folder21 folder22 folder23

我显然需要用递归函数。 我使用临时类成员方法在控制台应用程序为:

private: 
struct dirent *ep; 


void DirectoryReader::parseDirectory(char* readingDirectory) 
{ 
char* tempDirectory = (char*)malloc(sizeof(readingDirectory) + 200); 
string temp = readingDirectory; 

DIR *dp; 
dp = opendir (readingDirectory); 
    if (dp != NULL) 
    { 
     while (ep = readdir (dp)) 
     { 
     puts (ep->d_name); 

     temp += readingDirectory; 
     temp += "/"; 
     temp += ep->d_name; 

     char * buffer = new char[temp.length()]; 
     strcpy(buffer,temp.c_str()); 
     parseDirectory(buffer); 
     } 
     (void) closedir (dp); 
    } 
    else 
    perror ("Couldn't open the directory"); 

}

好吧,我不知道写得最好的代码,但我想最初有抓住了名的视图。但是它不能正常工作,因为它不止一次地考虑父目录的名称。即使我把调用相同的方法(不执行递归),前两个名字是。和......。为什么?

您能否建议我执行上述过程的功能或指示对此功能要求的更正?

+0

你能分享错误的输出吗? – 2012-06-19 08:13:24

+0

你在这里有一个错误的问题:当你分配'buffer'时,你不会为终止的''\ 0''字符分配空间。你也不会释放分配的内存。但是不使用临时缓冲区,为什么不直接将'temp.c_str()'传递给递归调用呢? –

+0

此外,您尝试缓存_all_文件。你必须检查它是否真的是一个目录,可以用'ep-> d_type == DT_DIR'来检查。或者如果没有'ep-> d_type'字段,你可以'stat'来获得类型。 –

回答

4

作为一些评论指出,boost :: filesystem是通常的路要走。 但是从你的代码看来,你仍然是C++的新手,所以我用C++惯用方法重写,增加了一些有用的显示。 HTH

#include <dirent.h> 
#include <iostream> 
#include <string> 
using namespace std; 

struct DirectoryReader 
{ 
    static void parseDirectory(string readingDirectory, int level); 
}; 

void DirectoryReader::parseDirectory(string readingDirectory, int level) 
{ 
    if (DIR *dp = opendir(readingDirectory.c_str())) 
    { 
     cout << string(level, ' ') << readingDirectory << endl; 
     while (struct dirent *ep = readdir(dp)) 
      if (ep->d_type == DT_DIR && ep->d_name[0] != '.') 
       parseDirectory(readingDirectory + "/" + ep->d_name, level + 1); 
     closedir(dp); 
    } 
    else 
     cerr << "Couldn't open the directory " << readingDirectory << endl; 
} 

int main_parsedir(int argc, char **argv) 
{ 
    if (argc > 1) 
     DirectoryReader::parseDirectory(argv[1], 0); 
    return 0; 
} 

注意,在你的代码,存储struct dirent *ep;类是完全错误的,因为你覆盖它,而递归...

2

目录枚举函数通常返回当前目录(。)和父目录( ..)链接。你需要忽略它们。另外你需要检查ep-> d_type。我已经为您编写了以下功能。请检查它是否按预期工作。 我没有使用输出的空格分隔符,因为单个文件夹中可以有空格字符。 另外,我不知道你将如何使用这个输出,因为它失去了树结构。

#include "dirent.h" 

const string theDelimiter = "\\"; 

class DirectoryReader 
{ 
public: 
    string DirectoryReader::parseDirectory(string readingDirectory, const string& aCurrentFolderName) 
    { 
     string aChildren; 
     aChildren += theDelimiter; 
     aChildren += aCurrentFolderName; 

     DIR *dp = opendir (readingDirectory.c_str()); 
     if (dp != NULL) 
     { 
      struct dirent *ep = NULL; 
      while ((ep = readdir (dp)) && ep->d_type == DT_DIR) 
      { 
       string aDirName = ep->d_name; 

       // Ignore current directory and the parent directory links 
       if(!aDirName.compare(".") || !aDirName.compare("..")) 
        continue; 

       // Form the full directory path 
       string aFullFolderName = readingDirectory; 
       aFullFolderName += string("\\"); 
       aFullFolderName += aDirName; 

       string aChildrenFolders = parseDirectory(aFullFolderName, aDirName); 
       if(aChildrenFolders.compare("")) 
       { 
        aChildren += aChildrenFolders; 
       } 
      } 

      (void) closedir (dp); 
     } 
     else 
      perror ("Couldn't open the directory"); 

     return aChildren; 
    } 
};