C ++递归搜索具有某些扩展名的文件
Posted
技术标签:
【中文标题】C ++递归搜索具有某些扩展名的文件【英文标题】:C++ Recursively searching for files with certain extensions 【发布时间】:2019-10-25 10:28:18 【问题描述】:我正在尝试编写一个函数来获取文件扩展名的std::set
,并递归搜索具有这些扩展名的文件,并将路径写入文件:
auto get_files(_In_ const std::wstring root, // root dir of search
_In_ const std::set<std::string> &ext, // extensions to search for)
_Out_ std::wofstream &ret /* file to write paths to */) -> int
HANDLE find = INVALID_HANDLE_VALUE;
// check root path
LPCWSTR root_path = root.c_str();
DWORD root_attrib = GetFileAttributesW(root_path);
if(root_attrib == INVALID_FILE_ATTRIBUTES) return 1; // root doesn't exist
if(!(root_attrib & FILE_ATTRIBUTE_DIRECTORY)) return 2; // root isn't a directory
LPCWSTR dir;
WIN32_FIND_DATAW fd;
// dir concat
std::wstring x = root.c_str();
x.append(L"\\*");
dir = x.c_str();
find = FindFirstFileW(dir, &fd);
do
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // current file is a dir
get_files(dir, ext, ret);
else
LPCWSTR current_ext = PathFindExtensionW(fd.cFileName);
if(ext.find(current_ext) != ext.end())
ret << fd.cFileName << '\n';
while (FindNextFileW(find, &fd) != 0);
FindClose(find);
return 0;
我收到以下错误:
E0304 重载函数“std::set<_kty _pr _alloc>::find [with _Kty=std::string, _Pr=std::less, _Alloc=std::allocator]”的实例不匹配参数列表
还有这个。
C2664 'std::_Tree_const_iterator>> std::_Tree>::find(const std::basic_string,std::allocator> &) const': 无法将参数 1 从 'const wchar_t *' 转换为 'const std ::basic_string,std::allocator> &'
【问题讨论】:
第二个错误说明了一切:cannot convert argument 1 from 'const wchar_t *' to (the worked out version of) std::string
.
还要注意dir
指向被销毁的std::wstring
的内容。如果这行得通,那只是偶然。
您无法将std::string
s 与std::wstring
s 进行比较。因此,要么将您的std::wstring
文件名转换为std::string
,要么使用std::wstring
s 的std::set
。您的选择。除非您使用指向已删除 std::string
的指针来修复未定义的行为,否则请准备好处理随机、不可预测、神秘的错误。
【参考方案1】:
两个问题:
std::set<std::string> &ext
和 LPCWSTR current_ext
之间的类型冲突。您可以使用std::set<std::wstring> &ext
来解决您的 E0304 错误。
正如@Botje 指出的,请注意std::wstring x
工作范围。您可以移除外部支架。
以下代码为我成功编译。请检查:
#include <shlwapi.h>
#include <set>
#include <fstream>
auto get_files(_In_ const std::wstring root, // root dir of search
_In_ const std::set<std::wstring> &ext, // extensions to search for)
_Out_ std::wofstream &ret /* file to write paths to */) -> int
HANDLE find = INVALID_HANDLE_VALUE;
// check root path
LPCWSTR root_path = root.c_str();
DWORD root_attrib = GetFileAttributesW(root_path);
if (root_attrib == INVALID_FILE_ATTRIBUTES) return 1; // root doesn't exist
if (!(root_attrib & FILE_ATTRIBUTE_DIRECTORY)) return 2; // root isn't a directory
LPCWSTR dir;
WIN32_FIND_DATAW fd;
// dir concat
std::wstring x = root.c_str();
x.append(L"\\*");
dir = x.c_str();
find = FindFirstFileW(dir, &fd);
do
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // current file is a dir
get_files(dir, ext, ret);
else
LPCWSTR current_ext = PathFindExtensionW(fd.cFileName);
if (ext.find(current_ext) != ext.end())
ret << fd.cFileName << '\n';
while (FindNextFileW(find, &fd) != 0);
FindClose(find);
return 0;
至于第二个错误C2664
我无法重现。确保向您发布重现这两个错误的确切代码。
【讨论】:
以上是关于C ++递归搜索具有某些扩展名的文件的主要内容,如果未能解决你的问题,请参考以下文章
如何递归地查找具有文本模式的文件,不包括某些目录和文件[重复]