Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;Windows API递归搜索未返回预期目录_C++_Winapi_Recursion - Fatal编程技术网

C++ c++;Windows API递归搜索未返回预期目录

C++ c++;Windows API递归搜索未返回预期目录,c++,winapi,recursion,C++,Winapi,Recursion,我目前正在尝试编写一个程序,使用windows.h中的实用程序递归搜索文件。当我执行以下代码时,文件路径会不断添加到上次搜索的文件路径中,但不会搜索文件夹,句柄也不会被标记为无效。这件事我已经烦了好几天了。为什么这不是递归搜索? 编辑:更正了使用位比较的代码。同样的错误也在发生 #include "stdafx.h" #include <iostream> #include <windows.h> // Microsoft Windows’ main libra

我目前正在尝试编写一个程序,使用windows.h中的实用程序递归搜索文件。当我执行以下代码时,文件路径会不断添加到上次搜索的文件路径中,但不会搜索文件夹,句柄也不会被标记为无效。这件事我已经烦了好几天了。为什么这不是递归搜索? 编辑:更正了使用位比较的代码。同样的错误也在发生

    #include "stdafx.h"
#include <iostream> 
#include <windows.h> // Microsoft Windows’ main library. 
#include <tchar.h> // Needed for _TEXT macro. 
#include "Strsafe.h" // Microsoft's library for secure strings.

using namespace std;
typedef wchar_t* LPWSTR, *PWSTR;
int layer = 0;

int recursionFindAbsraction(LPWSTR Dir, LPWSTR FilNam, LPWSTR filePath);
//original directory, new directory with *.* attached
//new directory with entire directory, new entire directory with *.* attached
int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t holder[MAX_PATH];//using this instead of string
    wchar_t direct[MAX_PATH];
    wchar_t filePath[MAX_PATH];

    wcout << "Please enter the directory you wish to search: " << endl;
    wcin >> direct;
    wcout << direct << endl;


    wcout << "Please enter the filename (program will automatically seach for all files like it): " << endl;
    wcin >> holder;
    wcout << holder << endl;

    recursionFindAbsraction(direct, holder, filePath);
    getchar();
    getchar();
    return 0;

}

int recursionFindAbsraction(LPWSTR Dir, LPWSTR FilNam, LPWSTR filePath){
    WIN32_FIND_DATAW ptrFileData;
    HANDLE hFile = NULL;
    BOOL bGetNext = true;

    wchar_t newDir[MAX_PATH];
    wchar_t newDir2[MAX_PATH];
    wchar_t filePathHolder[MAX_PATH];

    //add slash then put directory into new variable, newDir
    StringCchCatW(Dir, MAX_PATH, _TEXT("\\"));

    //Here, we split the path to avoid appending *.* to the current directory
    StringCchCopyW(filePathHolder, MAX_PATH, Dir);
    StringCchCopyW(newDir, MAX_PATH, Dir);
    StringCchCopyW(newDir2, MAX_PATH, Dir);
    StringCchCatW(newDir2, MAX_PATH, _TEXT("*.*"));
    hFile = FindFirstFile(newDir2, &ptrFileData);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("FindFirstFile failed (%d)\n", GetLastError());
        getchar();
        //return 0;
    }

    while (bGetNext){

        if ((ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)
        {
            int setLoop = (ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
            wcout << " file Attribute bitwise: " << setLoop;
            wcout << "file hidden " << endl;
            int counter = 0; counter++;
            wcout << "counter: " << counter << endl;
            wcout << "string compare: " << _wcsicmp(ptrFileData.cFileName, _TEXT("..")) << endl;
            wcout << "filename: " << ptrFileData.cFileName << endl;
            Sleep(100);
            /*
            if (_wcsicmp(ptrFileData.cFileName, _TEXT(".")) == 0){
                wcout << "Breaking1. " << endl;
                continue;
            }
            if (_wcsicmp(ptrFileData.cFileName, _TEXT("..")) == 0){
                wcout << "Breaking2. " << endl;
                continue;
            }*/
        }

        else
        {
            if (_wcsicmp(ptrFileData.cFileName, FilNam) == 0){
                wcout << "The first file found is: " << ptrFileData.cFileName << endl;
                //_tprintf(TEXT("The first file found is %s\n"), ptrFileData.cFileName);
                FindClose(hFile);
                //getchar();
                break;
            }
            if ((((ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) && ((ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0))
            {//must check to see if folder
                layer++;
                wcout << "Layer: " << layer << endl;
                ptrFileData.cFileName;
                //when this gets called because it's a folder, the name
                //gets added to the wrong directory
                StringCchCatW(newDir, MAX_PATH, ptrFileData.cFileName);
                wcout << " newDir/fulldir: " << newDir<< endl;
                //resolves full path name at this point
                wcout << "filePathHolder from last else: " << filePathHolder << endl;
                wcout << "filename: " << ptrFileData.cFileName << endl;

                recursionFindAbsraction(newDir, FilNam, filePath);

            }

        }
        wcout << "&ptrFileData: " << &ptrFileData << endl;
        wcout << "hFile: " << hFile << endl;
        bGetNext = FindNextFile(hFile, &ptrFileData);
        wcout << " exit: " << bGetNext<< endl;
    }
    FindClose(hFile);
    return 0;
}
#包括“stdafx.h”
#包括
#包括//Microsoft Windows的主库。
#包含_TEXT宏所需的//。
#包括“Strsafe.h”//Microsoft的安全字符串库。
使用名称空间std;
类型定义wchar_t*LPWSTR,*PWSTR;
int层=0;
int recursionFindAbsraction(LPWSTR Dir、LPWSTR FilNam、LPWSTR filePath);
//原始目录,附加了*.*的新目录
//新目录包含整个目录,新的完整目录包含*
int _tmain(int argc,_TCHAR*argv[]
{
wchar_t holder[MAX_PATH];//使用此选项而不是字符串
wchar_t direct[最大路径];
wchar_t文件路径[最大路径];
直接输出;

wcout这里是一个简单的递归搜索示例。注意,它使用
do{…}while(…);
,这使得跳到循环的末尾更容易

void findfile_recursive(const std::wstring &folder, const std::wstring &filename, std::vector<std::wstring> &files)
{
    std::wstring wildcard = folder + L"\\*";
    WIN32_FIND_DATA fd;
    HANDLE handle = FindFirstFile(wildcard.c_str(), &fd);
    if (handle == INVALID_HANDLE_VALUE)
        return;
    do
    {
        if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0)
            continue;
        std::wstring path = folder + L"\\" + std::wstring(fd.cFileName);

        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            findfile_recursive(path, filename, files);
        else if (_wcsicmp(fd.cFileName, filename.c_str()) == 0)
            files.push_back(path);

    } while (FindNextFile(handle, &fd));
    FindClose(handle);
}

int _tmain(int, wchar_t*[])
{
    std::vector<std::wstring> files;
    findfile_recursive(L"c:\\test", L"file.txt", files);
    for (auto file : files)
        std::wcout << file << endl;
}

FindFirstFile
总是首先返回
.
的条目,因此您对
的测试如果(\u wcsicmp(ptrFileData.cFileName,\u TEXT(“.”)==0)
将导致您立即跳出循环。您可能还希望使用
&
而不是
=
来测试属性,因为一次设置多个属性标志是很常见的。我没有使用
WIN32\u FIND\u DATAW
结构/类,但我确信您不应该比较
.dwfileattrib直接使用
FILE\u ATTRIBUTE\u DIRECTORY
属性,就像您不应该直接将其与
FILE\u ATTRIBUTE\u HIDDEN
进行比较一样。我敢打赌,这些是dwFileAttributes位字段(或int)中的标志,您应该检查dwFileAttributes字段中的每个位是否已启用。如
((ptrFileData.dwFileAttributes和文件属性目录)!=0)和((ptrFileData.dwFileAttributes和文件属性隐藏)==0)
但是如果你检查更多关于这方面的信息,那就更好了……对于ANSI字符集的构建,代码一般不能工作。因此,
t
的内容只是增加了冗长和复杂的内容。此外,你找不到Windows 9x安装来尝试ANSI构建。你一直附加到
newDir
,所以你找到的第二个目录将附加一个在第一个目录之后。可能不是你想要的。是的!从逻辑上讲,这就是我试图做的,但我在我的控制语句中迷失了方向。谢谢!
int recursionFindAbsraction(LPWSTR Dir, LPWSTR FilNam, LPWSTR filePath)
{
    ...
    //while (bGetNext)***
    do
    {
        if (wcscmp(ptrFileData.cFileName, L".") == 0 || wcscmp(ptrFileData.cFileName, L"..") == 0)
            continue;

        if (ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
            continue;//***skip hidden files and directories

        if (ptrFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            //***wrong redirection:
            //StringCchCatW(newDir, MAX_PATH, ptrFileData.cFileName);

            //***change to:
            StringCchCopyW(newDir, MAX_PATH, Dir);
            StringCchCatW(newDir, MAX_PATH, ptrFileData.cFileName);
            recursionFindAbsraction(newDir, FilNam, filePath);
        }
        else if (_wcsicmp(ptrFileData.cFileName, FilNam) == 0)
        {
            std::wcout << "The first file found is: " << Dir << ptrFileData.cFileName << endl;
        }

    } while (FindNextFile(hFile, &ptrFileData));//***

    FindClose(hFile);
    return 0;
}