如何解决如何在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);
}
}
解决方法
基本方法是:
- 实施目录的集合(堆栈或队列,取决于您要深度还是广度优先遍历)
- 使用要搜索的根目录将其初始化
- 运行一个循环,直到循环为空,每次循环弹出一个目录,重复其内容,并将在迭代过程中发现的所有新目录推送到集合中(在循环完成对每个目录的处理之后,将逐个处理该目录)目录)
基本上,递归将为您完成相同的工作,但是将您维护的堆栈范围限制为目录信息,而无需复制整个功能堆栈。
,有两种特定的方法:使用队列实现广度优先遍历和使用堆栈实现深度优先遍历。
我详细解释了如何使用队列(类似于使用堆栈):
- 首先将该文件夹的路径添加到队列中。
- 确定队列中的元素数是否大于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;
}
编辑:
有许多方法可以实现队列和堆栈。我建议您使用链式队列(或链式堆栈)。您可以找到许多在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 举报,一经查实,本站将立刻删除。