Perhaps you are looking for something like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
#include <iostream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
typedef std::vector <std::string> DirListing_t;
void GetDirListing( DirListing_t& result, const std::string& dirpath )
{
DIR* dir = opendir( dirpath.c_str() );
if (dir)
{
struct dirent* entry;
while ((entry = readdir( dir )))
{
struct stat entryinfo;
std::string entryname = entry->d_name;
std::string entrypath = dirpath + "/" + entryname;
if (!stat( entrypath.c_str(), &entryinfo ))
{
if (S_ISDIR( entryinfo.st_mode ))
{
if (entryname == "..");
else if (entryname == "." ) result.push_back( dirpath + "/" );
else GetDirListing( result, entrypath );
}
else
{
result.push_back( entrypath );
}
}
}
closedir( dir );
}
}
using namespace std;
int main( int argc, char* argv[] )
{
if (argc != 2)
{
cout << "usage:\n " << argv[ 0 ] << " DIRPATH\n"
<< "Display the directory tree for the directory DIRPATH.\n";
return 0;
}
DirListing_t dirtree;
GetDirListing( dirtree, argv[ 1 ] );
for (unsigned n = 0; n < dirtree.size(); n++)
cout << dirtree[ n ] << endl;
return 0;
}
|
It is a little different than yours -- it also lists the directory names it finds due to the condition on line 28 (using "/" in liu of "/."). The "/.." entry is still omitted. So, for example, my first test produced:
D:\prog\cc\foo> g++ -Wall -pedantic a.cpp
D:\prog\cc\foo> a .
./
./a.cpp
./a.exe
D:\prog\cc\foo> _
(Of course, I also tested it for other directories with recursion, etc...)
It does not list directories or files for which the user does not have access permissions (which causes
stat() to fail).
It also doesn't mess with the source path. Notice how I used a relative path? Here are three other runs and their results:
D:\prog\cc\foo> a D:\prog\cc\foo
D:\prog\cc\foo/
D:\prog\cc\foo/a.cpp
D:\prog\cc\foo/a.exe
D:\prog\cc\foo> a /prog/cc/foo
/prog/cc/foo/
/prog/cc/foo/a.cpp
/prog/cc/foo/a.exe
D:\prog\cc\foo> a ../a
../a/
../a/a.cpp
../a/a.exe
You may want to add in some normalization on the
dirpath argument to convert "\" to "/", collapse "." and ".." entries, and even get the absolute pathname (which is often unnecessary).
One last feature possibility is to return results relative to the initial
dirpath... this doesn't take too much extra work.
Hope this helps.