Click here to Skip to main content
11,813,557 members (43,474 online)
Click here to Skip to main content

Win32 file name iteration STL way

, 21 Nov 2004 101.5K 612 42
Rate this:
Please Sign up or sign in to vote.
This simple class shows how to iterate file names by using STL iterator interface.


Several times I worked with file names, I usually used Win32 API such as ::FindFirstFile.. But it turns out that it's so boring work. Finally, I realized I can use STL's great feature, iterator, to handle file name iteration. That's why I made a simple STL iterator class for file name iteration.


win32_file_iterator itBegin("c:\\*.*"), itEnd;
std::copy(itBegin, itEnd, ostream_iterator<std::string>(cout, "\n"));

The code above shows the simplest way to use the class. Actually, you can use almost all of STL algorithm, I think..

win32_file_iterator itBegin("c:\\*.*"), itEnd;
std::vector<std::string> vec(itBegin, itEnd);

You also can fill the STL container by using the constructor that takes begin iterator and end iterator.

Actually, win32_file_iterator class' constructor takes three parameters. The first one is the filter string that is for calling ::FindFirstFile function. Second one is the flag that specifies whether dereferenced path is full path or not. For example, if it's true, the returned path string is c:\test\aa.txt, otherwise it'll be aa.txt only. The last parameter is the other flags which specify file attribute. For simplicity, I used Win32 API's FILE_ATTRIBUTE_XXX flags..

If you want to get only directory names, and which is full path, the code will look like this:

win32_file_iterator itBegin("c:\\*", true, FILE_ATTRIBUTE_DIRECTORY);

So easy, huh?


#include <windows.h>
#include <iterator>
#include <string>

class win32_file_iterator : 
 public std::iterator<std::input_iterator_tag, std::string>

 class internal_handle_data{
  internal_handle_data():_h(NULL), _ref(0){}
  void setHandle(HANDLE handle){ _h = handle; }
  HANDLE getHandle(){ return _h; }
  void incRef(){ _ref++; }
  unsigned decRef(){ return --_ref; }
  operator HANDLE(){ return _h; }

  HANDLE _h;
  unsigned _ref;


 win32_file_iterator(std::string strfilter, bool bFullPath = false, 
   _bEnd(false), _bFullPath(bFullPath), _flag(flag){
        HANDLE h = ::FindFirstFile(strfilter.c_str(), &_wfd);
   _bEnd = true;
   std::string::size_type n1 = strfilter.find_last_of("\\");
   _strroot = strfilter.substr(0,n1+1);


 win32_file_iterator(win32_file_iterator& rhs){
  _handle = rhs._handle;
  _flag = rhs._flag;
  _bFullPath = rhs._bFullPath;
  _bEnd = rhs._bEnd;
  _wfd = rhs._wfd;
  _strfname = rhs._strfname;
  _strroot = rhs._strroot;  

  if(_handle.decRef() == 0 && _handle.getHandle() != NULL ){

 reference operator*(){
  return _strfname;

 bool operator==(const win32_file_iterator& rhs) const{
  return (_bEnd == rhs._bEnd);

 bool operator!=(const win32_file_iterator& rhs) const{
  return (_bEnd != rhs._bEnd);

 win32_file_iterator& operator++(){
  return *this;

 win32_file_iterator& operator++(int){
  return *this;


 void _findnext(){
  BOOL b = ::FindNextFile(_handle, &_wfd);
   _bEnd = true;

 void _chkvalid(WIN32_FIND_DATA& _wfd){
  if(_wfd.dwFileAttributes & _flag){

 void _getval(WIN32_FIND_DATA& wfd){
   _strfname = _strroot+ wfd.cFileName;
   _strfname = wfd.cFileName;

 int _flag;
 bool _bFullPath;
 bool _bEnd;
 internal_handle_data _handle;
 WIN32_FIND_DATA _wfd;
 std::string _strroot;
 std::string _strfname;


The code might have many terrible bugs. But what I want was to show the way we can use STL like iteration to find filenames. I wish it'll help you. You can use this code in whatever ways you want, comments are welcome..

And also check out boost::filesystem library.. it's well-written but a little bit heavy. It needs an additional DLL, I suppose.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

United States United States
study, study, That's all I can say Smile | :)

You may also be interested in...

Comments and Discussions

GeneralMy vote of 3 Pin
buyong8-Sep-11 21:25
memberbuyong8-Sep-11 21:25 
Questiontype &quot;reference&quot; ? Pin
Gerald E.24-Aug-05 23:39
memberGerald E.24-Aug-05 23:39 
AnswerRe: type &quot;reference&quot; ? Pin
mvalle9-Sep-05 3:23
membermvalle9-Sep-05 3:23 
AnswerRe: type "reference"? Pin
Hans-Martin Jensen13-May-06 1:37
memberHans-Martin Jensen13-May-06 1:37 
GeneralSeveral issues with the published code Pin
.:fl0yd:.2-Dec-04 4:33
member.:fl0yd:.2-Dec-04 4:33 
* Referencecounting related issues: The presented implementation has a number of issues, and hardly ever works except for the most trivial case. To illustrate this, take a look at this code snippet:
win32_file_iterator* pwfit = new win32_file_iterator( "C:\\*.*" );
win32_file_iterator wfit = *pwfit;
delete pwfit;
// wfit still holds a reference to the original HANDLE that has just been
// closed, with a reference count of 2.
Similar issues exist for the auto-generated assignment operator. A possible solution could be to use a static std::map<HANDLE, unsigned int> _handleReferences; member, and to insert code that deals with self-assignment, both for the copy-c'tor and the assignment operator.
While this solves the issues of reference counting, a more significant issue still remains: since the FindXyzFile API calls aren't stateless, a shared resource introduces a more severe problem. Operating on any given iterator potentially also silently modifies the state of another, in a worst-case scenario even to a point where it's state goes out of sync (see _bEnd).

* operator== and operator!=: First of all, unless there is a reason not to (like performance issues), these operators should always share a common implementation, i.e. operator!= should be expressed in terms of !operator==. More importantly, though, they should expose proper semantics. In the current implementation, all iterators are split in 2 groups, with members in each one comparing equal to any given other of that same group.

* post- and prefix increment operators: Again, the semantics are off. While the prefix operator is fine as it is, the postfix operator should return a temporary value that reflects the state of the iterator prior to the operation.

To sum it up, once you get rid of the shared handles, the remaining troublesome operators will be more natural to implement, and on top of that, expose more accurate semantics.

GeneralBrilliant Pin
Robert Bielik24-Nov-04 21:03
memberRobert Bielik24-Nov-04 21:03 
GeneralSuggestion Pin
Robert Bielik24-Nov-04 21:07
memberRobert Bielik24-Nov-04 21:07 
GeneralRe: Suggestion Pin
bektek25-Nov-04 8:15
memberbektek25-Nov-04 8:15 
GeneralOne very minor comment Pin
sdoyle24-Nov-04 6:47
membersdoyle24-Nov-04 6:47 
GeneralRe: One very minor comment Pin
bektek24-Nov-04 10:44
memberbektek24-Nov-04 10:44 
GeneralStlSoft and WinSTL Pin
Neville Franks23-Nov-04 23:18
memberNeville Franks23-Nov-04 23:18 
GeneralRe: StlSoft and WinSTL Pin
bektek23-Nov-04 23:20
memberbektek23-Nov-04 23:20 
GeneralRe: StlSoft and WinSTL Pin
Robert Bielik25-Nov-04 9:14
memberRobert Bielik25-Nov-04 9:14 
GeneralRe: StlSoft and WinSTL Pin
Neville Franks25-Nov-04 9:23
memberNeville Franks25-Nov-04 9:23 
GeneralRe: StlSoft and WinSTL Pin
.:fl0yd:.2-Dec-04 5:01
member.:fl0yd:.2-Dec-04 5:01 
GeneralRe: StlSoft and WinSTL Pin
Robert Bielik2-Dec-04 19:59
memberRobert Bielik2-Dec-04 19:59 
GeneralLooks nice. Pin
rtw170123-Nov-04 17:16
memberrtw170123-Nov-04 17:16 
GeneralTake a look at boost::filesystem Pin
Phan Manh Dan22-Nov-04 22:33
memberPhan Manh Dan22-Nov-04 22:33 
GeneralRe: Take a look at boost::filesystem Pin
bektek23-Nov-04 9:16
memberbektek23-Nov-04 9:16 
GeneralRe: Take a look at boost::filesystem Pin
occam26-Nov-04 5:37
memberoccam26-Nov-04 5:37 
GeneralRe: Take a look at boost::filesystem Pin
Anonymous26-Nov-04 22:09
sussAnonymous26-Nov-04 22:09 
GeneralRe: Take a look at boost::filesystem Pin
occam27-Nov-04 1:07
memberoccam27-Nov-04 1:07 
GeneralRe: Take a look at boost::filesystem Pin
nastanet28-Nov-04 22:24
membernastanet28-Nov-04 22:24 
GeneralRe: Take a look at boost::filesystem Pin
bektek29-Nov-04 0:17
memberbektek29-Nov-04 0:17 
GeneralRe: Take a look at boost::filesystem Pin
nastanet29-Nov-04 0:36
membernastanet29-Nov-04 0:36 
QuestionCould you explain? Pin
WREY22-Nov-04 5:28
memberWREY22-Nov-04 5:28 
AnswerRe: Could you explain? Pin
bektek22-Nov-04 6:33
memberbektek22-Nov-04 6:33 
GeneralRe: Could you explain? Pin
WREY23-Nov-04 3:45
memberWREY23-Nov-04 3:45 
GeneralLike you said... Pin
Nemanja Trifunovic21-Nov-04 14:26
memberNemanja Trifunovic21-Nov-04 14:26 
GeneralRe: Like you said... Pin
bektek21-Nov-04 16:34
memberbektek21-Nov-04 16:34 
GeneralRe: Like you said... Pin
Nemanja Trifunovic22-Nov-04 2:02
memberNemanja Trifunovic22-Nov-04 2:02 
GeneralRe: Like you said... Pin
bektek22-Nov-04 6:38
memberbektek22-Nov-04 6:38 
GeneralRe: Like you said... Pin
Harry Bosch29-Nov-04 3:46
memberHarry Bosch29-Nov-04 3:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151002.1 | Last Updated 21 Nov 2004
Article Copyright 2004 by bektek
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid