!!!解决了!!!
谢谢大家的帮助,现在一切正常。我按照@RSahu 的建议更改了我的代码并使其正常工作。
感谢您的所有意见,我一直坚持这个。
致@Basile:我一定会检查一下,但是对于这段特定的代码,我不会使用它,因为它看起来太复杂了:)但是感谢您的建议。
原始问题
我正在尝试制作一个 C++ 代码来列出给定目录及其子目录中的所有文件。
快速解释
想法是函数 list_dirs(_dir, _files, _current_dir)
将从顶层目录开始并将文件放入 vector _files
中,当它找到一个目录时它会调用自己在这个目录上。如果在子目录中,_current_dir
将被添加到文件名之前,因为我需要知道路径结构(它应该生成 sitemap.xml)。
在 list_dirs
中有一个对 list_dir
的调用,它只返回当前目录中的所有文件,不区分文件和目录。
我的问题
代码现在做的是列出原始目录中的所有文件,然后列出一个子目录中的所有文件,但跳过所有其他子目录。它会列出它们,但不会列出其中的文件。
更神秘的是,它只列出了这个特定目录中的文件,没有其他目录。我尝试在多个位置运行它,但它从未进入任何其他目录。
提前致谢,请注意我是 C++ 的初学者,所以请不要苛刻 ;)
列表目录
int list_dir(const std::string& dir, std::vector<std::string>& files){
DIR *dp;
struct dirent *dirp;
unsigned fileCount = 0;
if ((dp = opendir(dir.c_str())) == NULL){
std::cout << "Error opening dir." << std::endl;
}
while ((dirp = readdir(dp)) != NULL){
files.push_back(std::string (dirp->d_name));
fileCount++;
}
closedir(dp);
return fileCount;
}
和 LIST_DIRS
int list_dirs (const std::string& _dir, std::vector<std::string>& _files, std::string _current_dir){
std::vector<std::string> __files_or_dirs;
list_dir(_dir, __files_or_dirs);
std::vector<std::string>::iterator it = __files_or_dirs.begin();
struct stat sb;
while (it != __files_or_dirs.end()){
if (lstat((&*it)->c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
/* how to do this better? */
if (*it == "." || *it == ".."){
__files_or_dirs.erase(it);
continue;
}
/* here it should go into sub-directory */
list_dirs(_dir + *it, _files, _current_dir + *it);
__files_or_dirs.erase(it);
} else {
if (_current_dir.empty()){
_files.push_back(*it);
} else {
_files.push_back(_current_dir + "/" + *it);
}
++it;
}
}
}
最佳答案
主要问题在行中:
if (lstat((&*it)->c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
您在调用 lstat
时使用了目录条目的名称。当函数处理子目录时,条目名称不代表有效路径。你需要使用类似的东西:
std::string entry = *it;
std::string full_path = _dir + "/" + entry;
if (lstat(full_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
改进建议
更新 list_dir
,使其在输出中不包含 "."
或 ".."
。从一开始就排除这些文件对我来说很有意义。
int list_dir(const std::string& dir, std::vector<std::string>& files){
DIR *dp;
struct dirent *dirp;
unsigned fileCount = 0;
if ((dp = opendir(dir.c_str())) == NULL){
std::cout << "Error opening dir." << std::endl;
}
while ((dirp = readdir(dp)) != NULL){
std::string entry = dirp->d_name;
if ( entry == "." or entry == ".." )
{
continue;
}
files.push_back(entry);
fileCount++;
}
closedir(dp);
return fileCount;
}
在 list_dirs
中,不需要从 _files_or_dirs
中删除项目。可以使用 for
循环并通过删除从 _files_or_dirs
中删除项目的调用来简化代码。
我不清楚 _current_dir
的用途是什么。也许它可以被删除。
这是该函数的更新版本。 _current_dir
仅用于构造递归调用中参数的值。
int list_dirs (const std::string& _dir,
std::vector<std::string>& _files, std::string _current_dir){
std::vector<std::string> __files_or_dirs;
list_dir(_dir, __files_or_dirs);
std::vector<std::string>::iterator it = __files_or_dirs.begin();
struct stat sb;
for (; it != __files_or_dirs.end() ; ++it){
std::string entry = *it;
std::string full_path = _dir + "/" + entry;
if (lstat(full_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
/* how to do this better? */
/* here it should go into sub-directory */
list_dirs(full_path, _files, _current_dir + "/" + entry);
} else {
_files.push_back(full_path);
}
}
}
关于c++ - C++中的递归列表文件不会进入所有子目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34260221/