首页 > 技术文章 > Windows C++ 非递归式(stack)深度优先遍历目录

codeape 2014-07-11 12:40 原文

 1 #include <Windows.h>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <stack>
 6 
 7 typedef void (__stdcall *P_WALK_DIR_CALLBACK)(const std::string &In_strFilePath);
 8 
 9 int WalkDir(const char *In_pcRoot, P_WALK_DIR_CALLBACK In_pfunCallBack)
10 {
11     int         iRetVal = 0;
12     std::string strRoot;
13     std::stack<std::string> stkDirs;
14 
15     if (In_pcRoot == NULL || In_pfunCallBack == NULL)
16     {
17         iRetVal = -1;
18         goto fun_ret;
19     }
20 
21     strRoot = In_pcRoot;
22     if (strRoot.empty())
23     {
24         iRetVal = -2;
25         goto fun_ret;
26     }
27 
28     if (strRoot.back() != '\\' && strRoot.back() != '/')
29         strRoot += '\\';
30     stkDirs.push(strRoot);
31 
32     while (!stkDirs.empty())
33     {
34         std::string         strDirForWalk;
35         WIN32_FIND_DATAA    Win32FindData   = {0};
36         HANDLE              hFindHandle     = NULL;
37 
38         strDirForWalk = stkDirs.top();
39         stkDirs.pop();
40         hFindHandle = FindFirstFileA((strDirForWalk + "*").c_str(), &Win32FindData);
41         if (hFindHandle == INVALID_HANDLE_VALUE)
42             continue;
43 
44         if (!(strlen(Win32FindData.cFileName) == 1 && strncmp(Win32FindData.cFileName, ".", 1) == 0)
45             && !(strlen(Win32FindData.cFileName) == 2 && strncmp(Win32FindData.cFileName, "..", 2) == 0))
46         {
47             if (Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
48                 stkDirs.push(strDirForWalk + Win32FindData.cFileName + "\\");
49             else
50                 In_pfunCallBack(strDirForWalk + Win32FindData.cFileName);
51         }
52         while (FindNextFileA(hFindHandle, &Win32FindData))
53         {
54             if (!(strlen(Win32FindData.cFileName) == 1 && strncmp(Win32FindData.cFileName, ".", 1) == 0)
55                 && !(strlen(Win32FindData.cFileName) == 2 && strncmp(Win32FindData.cFileName, "..", 2) == 0))
56             {
57                 if (Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
58                     stkDirs.push(strDirForWalk + Win32FindData.cFileName + "\\");
59                 else
60                     In_pfunCallBack(strDirForWalk + Win32FindData.cFileName);
61             }
62         }
63 
64         if (hFindHandle != INVALID_HANDLE_VALUE)
65             FindClose(hFindHandle);
66     }
67 
68 fun_ret:
69     return iRetVal;
70 }
71 
72 void inline __stdcall WalkDirCallBack(const std::string &In_strFilePath)
73 {
74     printf("%s\n", In_strFilePath.c_str());
75     return;
76 }
77 
78 void main(int argc, char **argv)
79 {
80     WalkDir(argv[1], WalkDirCallBack);
81     return;
82 }

 

推荐阅读