How to walk through directory tree step by step?

天大地大妈咪最大 提交于 2019-12-04 17:07:12

Use the right tools. Boost is available as good as everywhere, and has the methods you want.

From http://rosettacode.org/wiki/Walk_a_directory/Recursively#C.2B.2B:

#include "boost/filesystem.hpp"
#include "boost/regex.hpp"
#include <iostream>

using namespace boost::filesystem;

int main()
{
  path current_dir("."); //
  boost::regex pattern("a.*"); // list all files starting with a
  for (recursive_directory_iterator iter(current_dir), end;
       iter != end;
       ++iter)
  {
    std::string name = iter->path().filename().string();
    if (regex_match(name, pattern))
      std::cout << iter->path() << "\n";
  }
}

remove the whole regex business if you don't care whether your file matches a certain pattern.

EDIT:

Could you please explain why it would be bad to use directly API calls ?

  1. it's ugly and hard to read, even harder to get right,
  2. it's not portable at all, and what's most important,
  3. there's a million corner cases you'd have to take care of, possibly, when using the raw win api. Boost has been written by people who did this a few hundred times and has underwent serious code review, so take the save route, and don't reinvent a wheel.

In essence, winapi is about two decades old; there's been a lot of usability improvement in the rest of the world. Unless you have a really good reason, I would try to abstract as much of it away as possible by using common libraries, such as Boost.

I think this does not solves my problem, I edited the original post to make it clearer.

basically need walk through tree without do/while, while or for...I need some kind of iterator, which can be stored for later use

That's exactly what my answer does: give you an Iterator in a for loop. I don't understand what's not fulfilling your Edit's specification about that.

In addition, it would be best to use only WinAPI, because it has to work on different computers with windows and installing boost could be a problem.

You don't have to install boost on any of these computers. Boost::filesystem can comfortable be linked in statically; also, the old-school windows way of doing this is just delivering boost_filesystem*.dll and boost_system*.dll along with your binary. However, if your goal is a single executable that contains all needed functions, you'll go for static linkage, anyway, so this is absolutely no problem.

Here is the native C++ way of doing it on Windows platform (using MFC framework):

void ListFiles(const CString& sPath)
{
   CFileFind finder;

   CString sWildcard(sPath);
   sWildcard += _T("\\*.*");

   BOOL bWorking = finder.FindFile(sWildcard);

   while (bWorking)
   {
      bWorking = finder.FindNextFile();

      if (finder.IsDots())
         continue;

      if (finder.IsDirectory())
      {
         CString sFilePath = finder.GetFilePath();
         // TODO: do stuff here
         ListFiles(sFilePath);
      }
   }

   finder.Close();
}

You can change wild card string to target specific files, like *.txt etc. You can also pass it as a parameter to this function to make it more general purpose.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!