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

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

我正在尝试使用WIN32 api在纯C语言中创建一个程序,以遍历目录树并列出其中的任何文件,如果找到文件夹,则应进入该目录以搜索其中的任何文件。在那里,我有一个可以正常工作的递归函数,但是有必要代码不是递归的。有人可以帮助修改代码以使其在没有递归功能的情况下工作吗?

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

    char SearchName[MAX_PATH],FullPath[MAX_PATH];

    memset(SearchName,sizeof(SearchName));
    memset(&Win32FindData,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,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,"File",MB_OK);
            }

        }

        FindClose(hFind);
    }
}

解决方法

基本方法是:

  1. 实施目录的集合(堆栈或队列,取决于您要深度还是广度优先遍历)
  2. 使用要搜索的根目录将其初始化
  3. 运行一个循环,直到循环为空,每次循环弹出一个目录,重复其内容,并将在迭代过程中发现的所有新目录推送到集合中(在循环完成对每个目录的处理之后,将逐个处理该目录)目录)

基本上,递归将为您完成相同的工作,但是将您维护的堆栈范围限制为目录信息,而无需复制整个功能堆栈。

,

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

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

  1. 首先将该文件夹的路径添加到队列中。
  2. 确定队列中的元素数是否大于0。如果元素数大于0,则遍历 对应于第一个元素的文件夹。如果其中有一个文件夹 此文件夹,将此文件夹的路径添加到队列中。扫描后 一个文件夹,第一个元素从队列中弹出,第二个 步骤继续。如果队列中没有元素,则执行第三步 被执行。
  3. 退出循环。

这是我用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;
}

编辑:

有许多方法可以实现队列和堆栈。我建议您使用链式队列(或链式堆栈)。您可以找到许多在Internet上实现它们的方法。我将提供一种实现方式供您参考。

以下是在纯C中实现的示例:

#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.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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-