使用Windows API的文件夹树的分层列表 < >我使用这个代码递归地在C++中列出一个文件夹及其子文件夹,代码工作得很好,我从许多StAcExpRoad问题中修改了它,询问递归文件夹列表。 #include <iostream> #include <string> #include <windows.h> #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif void findFiles (const std::string & spath) { struct HandleWrapper { HANDLE hFind; ~HandleWrapper () {if (hFind != INVALID_HANDLE_VALUE) ::FindClose (hFind); } } wrapper; size_t i = 1; WIN32_FIND_DATA FindFileData; std::string sourcepath = spath + std::string ("\\*.*"); wrapper.hFind = FindFirstFile (sourcepath.c_str (), &FindFileData); if (wrapper.hFind != INVALID_HANDLE_VALUE) do { std::string fullpath = std::string (spath) + std::string ("\\") + std::string (FindFileData.cFileName); if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && std::string FindFileData.cFileName) != "." && std::string (FindFileData.cFileName) != "..") findFiles (fullpath); else std::cout << i++ << "-" << FindFileData.cFileName<<std::endl; } while (FindNextFile (wrapper.hFind, &FindFileData)); } int main (int argc, char **argv) { std::string spath (argv[1]); findFiles (spath); return EXIT_SUCCESS; }

使用Windows API的文件夹树的分层列表 < >我使用这个代码递归地在C++中列出一个文件夹及其子文件夹,代码工作得很好,我从许多StAcExpRoad问题中修改了它,询问递归文件夹列表。 #include <iostream> #include <string> #include <windows.h> #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif void findFiles (const std::string & spath) { struct HandleWrapper { HANDLE hFind; ~HandleWrapper () {if (hFind != INVALID_HANDLE_VALUE) ::FindClose (hFind); } } wrapper; size_t i = 1; WIN32_FIND_DATA FindFileData; std::string sourcepath = spath + std::string ("\\*.*"); wrapper.hFind = FindFirstFile (sourcepath.c_str (), &FindFileData); if (wrapper.hFind != INVALID_HANDLE_VALUE) do { std::string fullpath = std::string (spath) + std::string ("\\") + std::string (FindFileData.cFileName); if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && std::string FindFileData.cFileName) != "." && std::string (FindFileData.cFileName) != "..") findFiles (fullpath); else std::cout << i++ << "-" << FindFileData.cFileName<<std::endl; } while (FindNextFile (wrapper.hFind, &FindFileData)); } int main (int argc, char **argv) { std::string spath (argv[1]); findFiles (spath); return EXIT_SUCCESS; },c++,recursion,winapi,C++,Recursion,Winapi,这个程序将列出A和B,然后它将进入C和它可能包含的任何子文件夹,然后对D执行相同的操作,然后它将在父文件夹中列出文件“E和F”,我真的希望它列出A、B、E和F,然后进入子文件夹C和D。 有没有想过不用借助外部库就可以完成这项工作?使用队列。如果遇到文件夹,请将其推送到队列中。当前目录中的所有子目录都完成后,从队列中拉出来,深入并重复,更像是修改过的BFS。使用队列。如果遇到文件夹,请将其推送到队列中。当当前目录中的所有子目录都完成后,从队列中拉出来,潜入并重复,更像是修改过的BFS。正如@Shu

这个程序将列出A和B,然后它将进入C和它可能包含的任何子文件夹,然后对D执行相同的操作,然后它将在父文件夹中列出文件“E和F”,我真的希望它列出A、B、E和F,然后进入子文件夹C和D。
有没有想过不用借助外部库就可以完成这项工作?

使用队列。如果遇到文件夹,请将其推送到队列中。当前目录中的所有子目录都完成后,从队列中拉出来,深入并重复,更像是修改过的BFS。

使用队列。如果遇到文件夹,请将其推送到队列中。当当前目录中的所有子目录都完成后,从队列中拉出来,潜入并重复,更像是修改过的BFS。

正如@Shubham所说,您需要使用队列来完成所需的功能

在遍历文件夹时,如果遇到文件夹,请将其推入队列,然后在遍历后从队列中弹出文件夹,从而实现文件夹的宽度遍历

以下是示例:

#include <Windows.h>
#include <iostream>
#include <queue>
using namespace std;
queue<std::string> qFolders;

void findFiles(string Path)
{
    WIN32_FIND_DATA findResult;
    HANDLE handle = NULL;

    if (qFolders.size() > 0)
    {
        std::string tempFolder = qFolders.front();
        tempFolder.append("\\*.*");
        handle = FindFirstFile(tempFolder.c_str(), &findResult);
        cout << qFolders.front() << endl;
        do
        {
            if (findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (lstrcmp(".", findResult.cFileName) == 0 || lstrcmp("..", findResult.cFileName) == 0)
                {
                    continue;
                }
                tempFolder = qFolders.front();
                tempFolder.append("\\").append(findResult.cFileName);
                qFolders.push(tempFolder);
            }
            else {
                cout << "  " << findResult.cFileName << endl;
            }
        } while (FindNextFile(handle, &findResult));
        qFolders.pop();
        if(!qFolders.empty())
        {
            findFiles(qFolders.front());
        }
    }
    if (handle)
    {
        FindClose(handle);
        handle = NULL;
    }
}

int main()
{
    qFolders.push("D:\\test\\t");
    findFiles(qFolders.front());
    return 0;
}
输出:


正如@Shubham所说,您需要使用队列来完成您想要的功能

在遍历文件夹时,如果遇到文件夹,请将其推入队列,然后在遍历后从队列中弹出文件夹,从而实现文件夹的宽度遍历

以下是示例:

#include <Windows.h>
#include <iostream>
#include <queue>
using namespace std;
queue<std::string> qFolders;

void findFiles(string Path)
{
    WIN32_FIND_DATA findResult;
    HANDLE handle = NULL;

    if (qFolders.size() > 0)
    {
        std::string tempFolder = qFolders.front();
        tempFolder.append("\\*.*");
        handle = FindFirstFile(tempFolder.c_str(), &findResult);
        cout << qFolders.front() << endl;
        do
        {
            if (findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (lstrcmp(".", findResult.cFileName) == 0 || lstrcmp("..", findResult.cFileName) == 0)
                {
                    continue;
                }
                tempFolder = qFolders.front();
                tempFolder.append("\\").append(findResult.cFileName);
                qFolders.push(tempFolder);
            }
            else {
                cout << "  " << findResult.cFileName << endl;
            }
        } while (FindNextFile(handle, &findResult));
        qFolders.pop();
        if(!qFolders.empty())
        {
            findFiles(qFolders.front());
        }
    }
    if (handle)
    {
        FindClose(handle);
        handle = NULL;
    }
}

int main()
{
    qFolders.push("D:\\test\\t");
    findFiles(qFolders.front());
    return 0;
}
输出:


只需将do/while循环拆分为两个循环。在第一个循环中,打印所有文件并忽略所有文件夹。在秒循环中,忽略所有文件并为每个文件夹调用递归函数。可能应该首先解决正确性问题。您永远无法使用代码页编码实现通用文件管理库。也就是说,为什么要重新发明轮子?C++已经为你提供了你需要的一切。为什么API中仍然存在这些函数?因为不是每个程序都是用C++编写的。对于那些用C++编写的程序,文件系统的实现最终将不得不调用OS。这不像编程语言生活在真空中,只需将do/while循环分成两个循环即可。在第一个循环中,打印所有文件并忽略所有文件夹。在秒循环中,忽略所有文件并为每个文件夹调用递归函数。可能应该首先解决正确性问题。您永远无法使用代码页编码实现通用文件管理库。也就是说,为什么要重新发明轮子?C++已经为你提供了你需要的一切。为什么API中仍然存在这些函数?因为不是每个程序都是用C++编写的。对于那些用C++编写的程序,文件系统的实现最终将不得不调用OS。这不像编程语言生活在真空中,你扩展了我的答案却没有投票,你扩展了我的答案却没有投票