如何在不使用c中任何递归函数的情况下遍历目录?
我正试图用纯C语言创建一个程序,使用WIN32 api迭代目录树并列出其中的任何文件,如果它找到一个文件夹,它应该进入该目录搜索其中的任何文件,我有一个递归函数可以完美地工作,但代码必须不是递归的。有人能帮助修改代码,使其在没有递归特性的情况下工作吗如何在不使用c中任何递归函数的情况下遍历目录?,c,winapi,C,Winapi,我正试图用纯C语言创建一个程序,使用WIN32 api迭代目录树并列出其中的任何文件,如果它找到一个文件夹,它应该进入该目录搜索其中的任何文件,我有一个递归函数可以完美地工作,但代码必须不是递归的。有人能帮助修改代码,使其在没有递归特性的情况下工作吗 void WINAPI IterateFiles(char* Directory) { HANDLE hFind; WIN32_FIND_DATA Win32FindData; char SearchName[MAX_PA
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);
}
}
基本方法是:
它基本上只是做递归为您所做的相同工作,但将您维护的堆栈范围限制为目录信息,而不复制整个函数堆栈。有两种特定方法:使用队列实现广度优先遍历和使用堆栈实现深度优先遍历 我详细解释了如何使用队列(类似于使用堆栈):
#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;
}