将文件夹和子文件夹中的所有文件 .doc 或 .docx 复制到另一个文件夹中
Copy all files .doc or .docx in folder and subfolder into another folder
我是 C++ 和 winapi 的新手,目前正在开发一个项目来创建一个 winapi 应用程序,该应用程序具有将一个驱动器中的所有文件 .doc 和 .docx 复制到另一个文件夹的功能。
以下是我所做的,但似乎没有用:
谁能告诉我如何正确执行此操作?
void cc(wstring inputstr) {
TCHAR sizeDir[MAX_PATH];
wstring search = inputstr + TEXT("\*");
wcscpy_s(sizeDir, MAX_PATH, search.c_str());
WIN32_FIND_DATA findfiledata;
HANDLE Find = FindFirstFile(sizeDir, &findfiledata);
do {
if (findfiledata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!wcscmp(findfiledata.cFileName, TEXT(".")) || !wcscmp(findfiledata.cFileName, TEXT(".."))) continue;
//checking folder or file
wstring dirfolder = inputstr + TEXT("\") + findfiledata.cFileName;
cc(dirfolder);
}
else {
wstring FileSearch = findfiledata.cFileName;
//.doc or docx
if (!wcscmp(FileSearch.c_str(), L".doc") || !wcscmp(FileSearch.c_str(), L".docx")) {
TCHAR src[256] = L"D:\test\";
wstring dirsrc = inputstr + TEXT("\") + findfiledata.cFileName;
_tprintf(TEXT(" %s \n"), dirsrc.c_str());
wcscat_s(src, findfiledata.cFileName);
CopyFile(dirsrc.c_str(), src, TRUE);
}
}
} while (FindNextFile(Find, &findfiledata) != 0);
FindClose(Find);
}
调用函数时这里的inputstr
就是我要搜索的驱动器,如cc(L"D:");
if (!wcscmp(FileSearch.c_str(), L".doc") || !wcscmp(FileSearch.c_str(), L".docx"))
这是比较整个文件名。我们只需要比较文件扩展名。 PathFindExtension
可用于查找文件扩展名:
const wchar_t* ext = PathFindExtension(findfiledata.cFileName);
if (_wcsicmp(ext, L".doc") == 0 || _wcsicmp(ext, L".docx") == 0)
{
const std::wstring path = inputstr + L"\" + findfiledata.cFileName;
std::wcout << path << '\n';
}
findfiledata
应为零初始化。
在该递归函数中添加 CopyFile
可能会导致问题。因为 FindNextFile
可以看到新复制的文件,并且该函数尝试再次复制它。
您可以将结果保存在字符串向量中,然后在 cc
完成后复制文件。
void cc(const std::wstring &inputstr, std::vector<std::wstring> &vec)
{
std::wstring wildcard{ inputstr + L"\*" };
WIN32_FIND_DATA find = { 0 };
HANDLE handle = FindFirstFile(wildcard.c_str(), &find);
if (handle == INVALID_HANDLE_VALUE)
return;
do
{
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!wcscmp(find.cFileName, L".") || !wcscmp(find.cFileName, L".."))
continue;
const std::wstring dir = inputstr + L"\" + find.cFileName;
cc(dir, vec);
}
else
{
const wchar_t* ext = PathFindExtension(find.cFileName);
if (_wcsicmp(ext, L".doc") == 0 || _wcsicmp(ext, L".docx") == 0)
{
const std::wstring path = inputstr + L"\" + find.cFileName;
vec.push_back(path);
}
}
} while (FindNextFile(handle, &find) != 0);
FindClose(handle);
}
用作
std::vector<std::wstring> result;
cc(L"D:\test", result);
for (const auto& e : result)
std::wcout << e << '\n';
注意,PathFindExtension
requires additional headers and libraries. If it's not available for some reason, and std::filesystem
不可用,这里有一个自己动手的方法:
std::wstring test = findfiledata.cFileName;
auto dot = test.find_last_of(L'.');
if (dot != std::wstring::npos)
{
auto ext = test.substr(dot);
for (auto& e : ext) e = towlower(e);
if (ext == L".doc" || ext == L".docx")
{
std::wstring path = inputstr + L"\" + findfiledata.cFileName;
std::wcout << path << '\n';
}
}
我是 C++ 和 winapi 的新手,目前正在开发一个项目来创建一个 winapi 应用程序,该应用程序具有将一个驱动器中的所有文件 .doc 和 .docx 复制到另一个文件夹的功能。 以下是我所做的,但似乎没有用:
谁能告诉我如何正确执行此操作?
void cc(wstring inputstr) {
TCHAR sizeDir[MAX_PATH];
wstring search = inputstr + TEXT("\*");
wcscpy_s(sizeDir, MAX_PATH, search.c_str());
WIN32_FIND_DATA findfiledata;
HANDLE Find = FindFirstFile(sizeDir, &findfiledata);
do {
if (findfiledata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!wcscmp(findfiledata.cFileName, TEXT(".")) || !wcscmp(findfiledata.cFileName, TEXT(".."))) continue;
//checking folder or file
wstring dirfolder = inputstr + TEXT("\") + findfiledata.cFileName;
cc(dirfolder);
}
else {
wstring FileSearch = findfiledata.cFileName;
//.doc or docx
if (!wcscmp(FileSearch.c_str(), L".doc") || !wcscmp(FileSearch.c_str(), L".docx")) {
TCHAR src[256] = L"D:\test\";
wstring dirsrc = inputstr + TEXT("\") + findfiledata.cFileName;
_tprintf(TEXT(" %s \n"), dirsrc.c_str());
wcscat_s(src, findfiledata.cFileName);
CopyFile(dirsrc.c_str(), src, TRUE);
}
}
} while (FindNextFile(Find, &findfiledata) != 0);
FindClose(Find);
}
调用函数时这里的inputstr
就是我要搜索的驱动器,如cc(L"D:");
if (!wcscmp(FileSearch.c_str(), L".doc") || !wcscmp(FileSearch.c_str(), L".docx"))
这是比较整个文件名。我们只需要比较文件扩展名。 PathFindExtension
可用于查找文件扩展名:
const wchar_t* ext = PathFindExtension(findfiledata.cFileName);
if (_wcsicmp(ext, L".doc") == 0 || _wcsicmp(ext, L".docx") == 0)
{
const std::wstring path = inputstr + L"\" + findfiledata.cFileName;
std::wcout << path << '\n';
}
findfiledata
应为零初始化。
在该递归函数中添加 CopyFile
可能会导致问题。因为 FindNextFile
可以看到新复制的文件,并且该函数尝试再次复制它。
您可以将结果保存在字符串向量中,然后在 cc
完成后复制文件。
void cc(const std::wstring &inputstr, std::vector<std::wstring> &vec)
{
std::wstring wildcard{ inputstr + L"\*" };
WIN32_FIND_DATA find = { 0 };
HANDLE handle = FindFirstFile(wildcard.c_str(), &find);
if (handle == INVALID_HANDLE_VALUE)
return;
do
{
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!wcscmp(find.cFileName, L".") || !wcscmp(find.cFileName, L".."))
continue;
const std::wstring dir = inputstr + L"\" + find.cFileName;
cc(dir, vec);
}
else
{
const wchar_t* ext = PathFindExtension(find.cFileName);
if (_wcsicmp(ext, L".doc") == 0 || _wcsicmp(ext, L".docx") == 0)
{
const std::wstring path = inputstr + L"\" + find.cFileName;
vec.push_back(path);
}
}
} while (FindNextFile(handle, &find) != 0);
FindClose(handle);
}
用作
std::vector<std::wstring> result;
cc(L"D:\test", result);
for (const auto& e : result)
std::wcout << e << '\n';
注意,PathFindExtension
requires additional headers and libraries. If it's not available for some reason, and std::filesystem
不可用,这里有一个自己动手的方法:
std::wstring test = findfiledata.cFileName;
auto dot = test.find_last_of(L'.');
if (dot != std::wstring::npos)
{
auto ext = test.substr(dot);
for (auto& e : ext) e = towlower(e);
if (ext == L".doc" || ext == L".docx")
{
std::wstring path = inputstr + L"\" + findfiledata.cFileName;
std::wcout << path << '\n';
}
}