Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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_Winapi - Fatal编程技术网

如何在不使用c中任何递归函数的情况下遍历目录?

如何在不使用c中任何递归函数的情况下遍历目录?,c,winapi,C,Winapi,我正试图用纯C语言创建一个程序,使用WIN32 api迭代目录树并列出其中的任何文件,如果它找到一个文件夹,它应该进入该目录搜索其中的任何文件,我有一个递归函数可以完美地工作,但代码必须不是递归的。有人能帮助修改代码,使其在没有递归特性的情况下工作吗 void WINAPI IterateFiles(char* Directory) { HANDLE hFind; WIN32_FIND_DATA Win32FindData; char SearchName[MAX_PA

我正试图用纯C语言创建一个程序,使用WIN32 api迭代目录树并列出其中的任何文件,如果它找到一个文件夹,它应该进入该目录搜索其中的任何文件,我有一个递归函数可以完美地工作,但代码必须不是递归的。有人能帮助修改代码,使其在没有递归特性的情况下工作吗

void WINAPI IterateFiles(char* Directory)
{
    HANDLE hFind;
    WIN32_FIND_DATA Win32FindData;

    char SearchName[MAX_PATH], FullPath[MAX_PATH];

    memset(SearchName, 0, sizeof(SearchName));
    memset(&Win32FindData, 0, sizeof(WIN32_FIND_DATA));

    sprintf(SearchName, "%s\\*", Directory);

    hFind = FindFirstFileA(SearchName, &Win32FindData);

    if (hFind != INVALID_HANDLE_VALUE)
    {
        while (FindNextFileA(hFind, &Win32FindData))
        {
            if (Win32FindData.cFileName[0] == '.')
            {
                continue;
            }

            memset(FullPath, 0, sizeof(FullPath));
            sprintf(FullPath, "%s\\%s", Directory, Win32FindData.cFileName);

            if (Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                MessageBoxA(NULL, FullPath, "Directory", MB_OK);
                IterateFiles(FullPath);
            }

            else
            {
                MessageBoxA(NULL, FullPath, "File", MB_OK);
            }

        }

        FindClose(hFind);
    }
}
基本方法是:

  • 实现要搜索的目录集合(堆栈或队列,具体取决于您希望深度优先还是广度优先遍历)
  • 使用要搜索的根目录初始化它
  • 运行一个循环,直到其为空,每次弹出一个目录,迭代其内容,并将迭代过程中发现的任何新目录推送到集合中(在循环完成处理每个目录时逐个处理)
  • 它基本上只是做递归可以为您做的相同工作,但将您维护的堆栈范围限制为目录信息,而不复制整个函数堆栈。

    基本方法是:

  • 实现要搜索的目录集合(堆栈或队列,具体取决于您希望深度优先还是广度优先遍历)
  • 使用要搜索的根目录初始化它
  • 运行一个循环,直到其为空,每次弹出一个目录,迭代其内容,并将迭代过程中发现的任何新目录推送到集合中(在循环完成处理每个目录时逐个处理)

  • 它基本上只是做递归为您所做的相同工作,但将您维护的堆栈范围限制为目录信息,而不复制整个函数堆栈。

    有两种特定方法:使用队列实现广度优先遍历和使用堆栈实现深度优先遍历

    我详细解释了如何使用队列(类似于使用堆栈):

  • 首先将此文件夹的路径添加到队列中
  • 确定队列中的元素数是否大于0。如果元素数大于0,则遍历 与第一个元素对应的文件夹。如果在中有一个文件夹 若要删除此文件夹,请将此文件夹的路径添加到队列中。扫描后 一个文件夹,第一个元素从队列中弹出,第二个元素从队列中弹出 步骤继续。如果队列中没有元素,则第三步 被执行
  • 退出循环
  • 下面是我用C++实现的示例:

    #include <Windows.h>
    #include <iostream>
    #include <queue>
    using namespace std;
    
    void QueryFileCounts(string Path)
    {
        queue<std::string> qFolders;
        qFolders.push(Path);
    
        WIN32_FIND_DATA findResult;
        HANDLE handle = NULL;
    
        while (qFolders.size() > 0)
        {
            std::string tempFolder = qFolders.front();
            tempFolder.append("\\*.*");
            handle = FindFirstFile(tempFolder.c_str(), &findResult);
            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 (handle)
        {
            FindClose(handle);
            handle = NULL;
        }
    }
    
    int main()
    {
        QueryFileCounts("D:\\test");
        return 0;
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    无效查询文件计数(字符串路径)
    {
    排队等候;
    qFolders.push(路径);
    WIN32_FIND_DATA findResult;
    HANDLE=NULL;
    而(qFolders.size()>0)
    {
    std::string tempFolder=qFolders.front();
    tempFolder.append(\\*.*);
    handle=FindFirstFile(tempFolder.c_str(),&findResult);
    做
    {
    if(findResult.dwFileAttributes和文件属性目录)
    {
    如果(lstrcmp(“.”,findResult.cFileName)==0 | | lstrcmp(“…”,findResult.cFileName)==0)
    {
    继续;
    }
    tempFolder=qFolders.front();
    tempFolder.append(“\\”).append(findResult.cFileName);
    qFolders.push(临时文件夹);
    }
    否则{
    cout-rear=NULL;
    队列->大小=0;
    }
    int QueueEmpty(结构队列*队列)
    {
    返回(队列->大小==0);
    }
    void QueuePush(结构队列*队列,常量字符*数据)
    {
    结构链接*节点;
    node=(结构链接*)malloc(sizeof(结构链接));
    如果(节点)
    {
    strcpy(节点->数据,数据);
    节点->下一步=空;
    if(QueueEmpty(queue))
    {
    队列->前端=节点;
    队列->后方=节点;
    }
    其他的
    {
    队列->后方->下一步=节点;
    队列->后方=节点;
    }
    ++队列->大小;
    }
    }
    int QueuePop(结构队列*队列)
    {
    if(QueueEmpty(queue))
    {
    返回0;
    }
    struct Link*tmp=queue->front;
    队列->前方=队列->前方->下一步;
    免费(tmp);
    --队列->大小;
    返回1;
    }
    void QueueDestroy(结构队列*队列)
    {
    结构链接*tmp;
    while(队列->前面)
    {
    tmp=队列->前方;
    队列->前方=队列->前方->下一步;
    免费(tmp);
    }
    }
    无效查询文件计数(常量字符*路径)
    {
    结构队列qFolders;
    QueueInit(&qFolders);
    队列推送(&Q文件夹,路径);
    WIN32_FIND_DATA findResult;
    HANDLE=NULL;
    而(qFolders.size>0)
    {
    char tempFolder[1024];
    strcpy(临时文件夹,qFolders.front->data);
    sprintf(tempFolder,“%s\\*.*”,tempFolder);
    handle=FindFirstFile(tempFolder,&findResult);
    做
    {
    if(findResult.dwFileAttributes和文件属性目录)
    {
    如果(lstrcmp(“.”,findResult.cFileName)==0 | | lstrcmp(“…”,findResult.cFileName)==0)
    {
    继续;
    }
    strcpy(临时文件夹,qFolders.front->data);
    sprintf(tempFolder,“%s\\%s”,tempFolder,findResult.cFileName);
    队列推送(&qFolders,tempFolder);
    }
    否则{
    printf(“%s\n”,findResult.cFileName);
    }
    }while(FindNextFile(handle,&findResult));
    QueuePop(和qFolders);
    }
    if(句柄)
    {
    FindClose(手柄);
    handle=NULL;
    }
    队列销毁(和qFolders);
    }
    int main()
    {
    查询文件计数(“D:\\test”);
    返回0;
    }
    
    有两种特定的方法:使用队列实现的广度优先遍历和使用堆栈实现的深度优先遍历

    我详细解释了如何使用队列(类似于使用堆栈):

  • 首先将此文件夹的路径添加到
    #include <stdio.h>
    #include <Windows.h>
    #include <string.h>
    struct Link 
    {
        char data[1024];
        struct Link* next;
    };
    
    struct Queue
    {
        struct Link* front;
        struct Link* rear;
        int size;
    };
    
    void QueueInit(struct Queue* queue)
    {
        queue->front = NULL;
        queue->rear = NULL;
        queue->size = 0;
    }
    
    int QueueEmpty(struct Queue* queue)
    {
        return (queue->size == 0);
    }
    
    void QueuePush(struct Queue* queue, const char * data)
    {
        struct Link* node;
        node = (struct Link*)malloc(sizeof(struct Link));
        if (node)
        {
            strcpy(node->data, data);
            node->next = NULL;
            if (QueueEmpty(queue))
            {
                queue->front = node;
                queue->rear = node;
            }
            else
            {
                queue->rear->next = node;
                queue->rear = node;
            }
            ++queue->size;
        }
        
    }
    
    int QueuePop(struct Queue* queue)
    {
        if (QueueEmpty(queue))
        {
            return 0;
        }
        struct Link* tmp = queue->front;
        queue->front = queue->front->next;
        free(tmp);
        --queue->size;
        return 1;
    }
    
    void QueueDestroy(struct Queue* queue)
    {
        struct Link* tmp;
        while (queue->front)
        {
            tmp = queue->front;
            queue->front = queue->front->next;
            free(tmp);
        }
    }
    
    
    void QueryFileCounts(const char * Path)
    {
        struct Queue qFolders;
        QueueInit(&qFolders);
        QueuePush(&qFolders, Path);
        WIN32_FIND_DATA findResult;
        HANDLE handle = NULL;
    
        while (qFolders.size > 0)
        {
            char tempFolder[1024];
            strcpy(tempFolder, qFolders.front->data);
            sprintf(tempFolder, "%s\\*.*", tempFolder);
            handle = FindFirstFile(tempFolder, &findResult);
            do
            {
                if (findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    if (lstrcmp(".", findResult.cFileName) == 0 || lstrcmp("..", findResult.cFileName) == 0)
                    {
                        continue;
                    }
                    strcpy(tempFolder, qFolders.front->data);
                    sprintf(tempFolder, "%s\\%s", tempFolder, findResult.cFileName);
                    QueuePush(&qFolders, tempFolder);
                }
                else {
                    printf("%s\n", findResult.cFileName);
                }
            } while (FindNextFile(handle, &findResult));
            QueuePop(&qFolders);
        }
        if (handle)
        {
            FindClose(handle);
            handle = NULL;
        }
        QueueDestroy(&qFolders);
    }
    
    int main()
    {
        QueryFileCounts("D:\\test");
        return 0;
    }