CS253: Software Development with C++

Spring 2018

Iterator

Iterator Lab                

In this lab, we will look at iterating over a non-container. We could have just as well called this the “Virtual Container Lab”, but the multiple meanings of virtual would confuse things.                 

The files for this lab are in ~cs253/Labs/Iterator. Copy them to a temporary directory.                 

A Non-Container                

If someone asked you to name the continents, you might say:

(Then, an enjoyable argument about Europe would break out.)                 

Did you actually have that list of continents written down, and you iterated over them? Probably not. Instead, you generated that list, as needed. Similarly, in C++, we sometimes want to iterate over “containers” that don’t really hold anything, but instead have dynamically-generated contents.                 

Directory Iteration with Linux System Calls                

Consider this program, dir-simple.cc:                 

    #include <iostream>
    #include <dirent.h>

    using namespace std;

    int main() {
        DIR *dp = opendir(".");
        while (dirent *d = readdir(dp))
            if (string(d->d_name) != "." && string(d->d_name) != "..")
        	cout << "Filename: " << d->d_name << '\n';
        closedir(dp);
        return 0;
    }

It displays all the files in the current directory (“.”) except for the current directory itself (“.”) and the parent directory (“..”). It does so with the opendir / readdir / closedir functions.                 

Every time readdir is called, it reads another directory entry from the disk, in a system-dependent manner. It returns a pointer to a struct that contains the d_name field, a C-style string. If readdir runs out of names in the directory, it returns a null pointer.                 

This program is certainly not in our usual C++ style, but it works.                 

Directory Iteration in the C++ Manner                

dir-object.cc is more in C++ style:                 

    #include <iostream>
    #include "Directory.h"

    using std::cout;

    int main() {
        Directory dir(".");
        for (auto name : dir)
            cout << "Filename: " << name << '\n';
    }

We have a “container”, of type Directory, initialized with “.”, the current directory. We then iterate over that container using a typical for-each loop.                 

Of course, there’s complexity hidden in Directory.h and Directory.cc. Unsurprisingly, they use the opendir / readdir / closedir functions.                 

Understanding the code                

As a group, discuss and understand Directory.h and Directory.cc.                 

Points to consider:

Exercises                

  1. What happens when the Directory ctor is given a non-existant directory name? Try it. Fix it.
  2. It’s cumbersome for the . and .. filtering code to be in operator++. Make it a separate, private method called .wanted().
  3. Add a second, optional, argument to the Directory ctor that specifies a regular expression of filenames to match. For example, Dir foo(".", "a.*b") would yield rabbit and catbird, but not zulu. Do the pattern-matching in your new .wanted() method.
  4. Show your work to the TA.

User: Guest                 

Check: HTML CSS
Edit History Source

Modified: 2018-05-02T21:57                 

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building