Click here to Skip to main content
15,886,035 members
Articles / Programming Languages / C++

CEnum - File Enumeration and File Globbing Class

Rate me:
Please Sign up or sign in to vote.
4.45/5 (5 votes)
6 Dec 2008CPOL12 min read 52.5K   1.2K   48  
CEnum is used for enumeration of files and directories using wildcard matching (globbing)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>CEnum1: Advanced Usage</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.7.1 -->
<script type="text/javascript">
<!--
function changeDisplayState (e){
  var num=this.id.replace(/[^[0-9]/g,'');
  var button=this.firstChild;
  var sectionDiv=document.getElementById('dynsection'+num);
  if (sectionDiv.style.display=='none'||sectionDiv.style.display==''){
    sectionDiv.style.display='block';
    button.src='open.gif';
  }else{
    sectionDiv.style.display='none';
    button.src='closed.gif';
  }
}
function initDynSections(){
  var divs=document.getElementsByTagName('div');
  var sectionCounter=1;
  for(var i=0;i<divs.length-1;i++){
    if(divs[i].className=='dynheader'&&divs[i+1].className=='dynsection'){
      var header=divs[i];
      var section=divs[i+1];
      var button=header.firstChild;
      if (button!='IMG'){
        divs[i].insertBefore(document.createTextNode(' '),divs[i].firstChild);
        button=document.createElement('img');
        divs[i].insertBefore(button,divs[i].firstChild);
      }
      header.style.cursor='pointer';
      header.onclick=changeDisplayState;
      header.id='dynheader'+sectionCounter;
      button.src='closed.gif';
      section.id='dynsection'+sectionCounter;
      section.style.display='none';
      section.style.marginLeft='14px';
      sectionCounter++;
    }
  }
}
window.onload = initDynSections;
-->
</script>
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="navpath"><a class="el" href="index.html">A simple manual</a>
  </div>
</div>
<div class="contents">
<h1><a class="anchor" name="advanced">Advanced Usage </a></h1>This page is for advanced users. Make sure you have first read <a class="el" href="basic.html">Basic Usage</a><p>
<h3><a class="anchor" name="Instantiating4"></a>Instantiating</h3>
<p>
There are two constructors for greater flexibility when using <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code><p>
<pre lang="c++">// ... using default constructor</pre><p>
<pre lang="c++"><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a> enumerator;</pre><p>
<pre lang="c++"><span class="code-comment">//</span> set options
enumerator.sExcPatternDirs  = _T("Post Black album Metallica");
enumerator.sIncPatternDirs  = _T("Iron Maiden");
enumerator.sExcPatternFiles = _T("*.wma");
enumerator.sIncPatternFiles = _T("*.mp3;*.ogg");
enumerator.bRecursive       = true;    
enumerator.bFullPath        = true;
enumerator.bNoCaseDirs      = true;    
enumerator.bNoCaseFiles     = true;</pre><p>
<pre lang="c++">enumerator.EnumerateAll(_T("D:\\Music"));</pre><p>
<pre lang="c++">list&lt;string&gt; * pQualityMetal = enumerator.GetFiles();</pre> <br>
 <p>
<b>... or the same thing with fewer lines: </b><p>
<pre lang="c++">// ... using parameterized constructor</pre><p>
<pre lang="c++"><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a> enumerator(   
                    _T("D:\\Music"), 
                    _T("Post Black album Metallica"), 
                    _T("*.wma"),
                    _T("Iron Maiden"),
                    _T("*.mp3;*.ogg"),
                    true,
                    true,
                    true,
                    true
                 );</pre><p>
<pre lang="c++">list&lt;string&gt; * pQualityMetal = enumerator.GetFiles();</pre><p>
<br>
<p>
<b>... or the really simple way (if default values work for you):</b><p>
<pre lang="c++">// ... using parameterized constructor with default values</pre><p>
<pre lang="c++"><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a> enumerator( _T("D:\\Music") );</pre><p>
<pre lang="c++">list&lt;string&gt; * pQualityMetal = enumerator.GetFiles();</pre><p>
<br>
 <h3><a class="anchor" name="Classdestructor5"></a>Class Destructor</h3>
<p>
Let me quote the very first book I read about C++, Jesse Liberty's "Teach yourself C++ in 21 days": "If you are writing a function that needs to create memory and then pass it back to the calling function, consider changing your interface. Have the calling function allocate the memory and then pass it into your function by reference. This moves all memory management out of your program and back to the function that is prepared to delete it."<p>
Why did I not follow this great advice? Well firstly, this was designed to be similar to C# class <code>Directory</code> (and in C# garbage collector takes care of memory management, thus the caller does not care about memory issues). And secondly, I wanted a class that that would be easy to use. Remember, <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code>'s job is simply to create a list of file names.<p>
So, here is how things work in <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code>: <ol>
<li>
Constructor allocates two lists </li>
<li>
After enumeration process ends, pointers to two lists are returned to calling function </li>
<li>
Pointer(s) to list(s) are deleted in destructor of <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> </li>
</ol>
<p>
This means that your enumeration list(s) will live only as long as is the life time of <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> object that created it !!! You cannot pass the pointer to some other function. If you would like to do that, you either need to create a copy of the list, or comment out some (or all) delete statements in destructor.<p>
Is this a bad design? It just might be, but simplicity of use was my primary issue when I designed this class. I wanted to be able to enumerate directory in a single line (see example above), do something with those files (e.g. display them on the screen) and then to forget about <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> object and all the lists it allocated. If you want to do it 'properly' <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> can be easily adapted to use lists allocated by client application, all that is needed is to add one more constructor and to comment out few lines in destructor.<p>
<br>
 <h3><a class="anchor" name="Classmembers6"></a>Class Members</h3>
<p>
This is the list of CEnum's public member varibales through which user can set desired options:<p>
<ul>
<li>
<b>bRecursive</b><br>
Description: if true subdirectories will be enumerated too<br>
Default value: false <p>
</li>
<li>
<b>bFullPath</b><br>
Description: if true files will be enumerated using file's full path, otherwise list will contain file names only<br>
Default value: false <p>
</li>
<li>
<b>bNoCaseDirs</b><br>
Description: if true case will be ignored when searching directory (and only directory) names<br>
Default value: false <p>
</li>
<li>
<b>bNoCaseFiles</b><br>
Description: if true case will be ignored when searching file (and only file) names<br>
Default value: false <p>
</li>
<li>
<b>sIncPatternFiles</b><br>
Description: matching pattern for files you wish to include in your search. Wild cards * and ? are supported. If you have more than one search pattern, separate them with semicolon.<br>
Default value: empty string <br>
Examples: <ul>
<li>
"*.mp3;*.mp4"  </li>
<li>
"*.mp?" (same as first example)  </li>
<li>
"*.mp3;iron maid*;latest*"  </li>
</ul>
<p>
Note that in case of Include patterns, empty string means "enumerate all", i.e. everything is included !! <p>
</li>
<li>
<b>sExcPatternFiles</b><br>
Description: matching pattern for files you wish to exclude from your search. Wild cards * and ? are supported. If you have more that one search pattern, separate them with semicolon.<br>
Default value: empty string <br>
Examples: <ul>
<li>
"*.mp3;*.mp4"  </li>
<li>
"*.mp?" (same as first example)  </li>
<li>
"*.mp3;iron maid*;latest*"  </li>
</ul>
<p>
Note that in case of Exclude patterns, empty string means "enumerate none", i.e. nothing is excluded!!<br>
Also, in case of conflict, Exclude pattern has presedence over Include pattern. <p>
</li>
<li>
<b>sIncPatternDirs</b> same as <b>sIncPatternFiles</b> above, just for directories. <p>
</li>
<li>
<b>sExcPatternDirs</b> same as <b>ExcPatternFiles</b> above, just for directories.  </li>
</ul>
<p>
<br>
<p>
<h3><a class="anchor" name="STLlistvs.MFCcollectionclasses7"></a>STL List vs. MFC Collection Classes</h3>
<p>
<code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> can give you a variety of lists:<p>
<pre lang="c++">// ... show all containers <a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a> can return</pre><p>
<pre lang="c++"><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a> enumerator(_T("C:\\"));</pre><p>
<pre lang="c++">list&lt;string&gt; * pSTLlistFiles   = enumerator.GetFiles();
list&lt;string&gt; * pSTLlistDirs    = enumerator.GetDirs();</pre><p>
<pre lang="c++">StringList   * pMFClistFiles   = enumerator.GetFilesAsCStringList();
StringList   * pMFClistDirs    = enumerator.GetDirsAsCStringList();</pre><p>
<pre lang="c++">StringArray  * pMFCArrayFiles  = enumerator.GetFilesAsCStringArray();
StringArray  * pMFCArrayDirs   = enumerator.GetDirsAsCStringArray();</pre><p>
Since <code><a class="el" href="class_c_enum.html" title="CEnum - File Enumeration and File Globbing Class.">CEnum</a></code> was written using STL, the only two lists created during the execution are two lists returned by <code>GetDirs()</code> and <code>GetFiles()</code> functions. All four MFC containers (two <code>CStringArrays</code> and two <code>CStringLists</code>) are created only when you call conversion functions (<code>GetFilesAs...</code> and <code>GetDirsAs...</code>). In fact, all MFC related stuff is hidden behind preprocessor directives and is by default inactive (i.e. it does not compile). If you need this functionality, then just uncomment <code>//# define MFC</code> line and recompile. <p>
<br>
<p>
That is it, I wish you a happy, happy enumerating :-). </div>
<hr size="1"><address style="text-align: right;"><small>Generated on Wed Dec 3 12:45:12 2008 for CEnum1 by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.7.1 </small></address>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Croatia Croatia
Nothing to brag about.
Just another engineer who works as a software developer last couple of years.

Comments and Discussions