views:

77

answers:

4

I need to generate a container of filenames within a directory in C++ and it must be cross platform compatible. Someone recommended using the WIN32_FIND_DATA data structure. Is this the best option and if so how would I implement it?

The user will not enter the filenames, but rather the C++ function will automatically search the directory and create a container of filenames. I don't know how to read in filenames like this either.

I have a strong focus on standards too, so <dirent.h> is not an ideal solution because it is not ISO C standard even though its a header in the C POSIX library.

+3  A: 

I'm guessing WIN32_FIND_DATA isn't your best bet for cross platform, but there are probably libraries to help provide it on linux.

Consider using boost filesystem to dump the files into a std::vector.

Something like this (adapted from here):

void show_files(const path & directory)
{
  if(!exists(directory)) return;

  directory_iterator end ;
  for( directory_iterator iter(directory) ; iter != end ; ++iter )
    if (is_directory(*iter)) continue;  // skip directories
    cout << "File: " << iter->native_file_string() << "\n" ;
  }
}
Stephen
Could you provide some sample code using boost please?
Elpezmuerto
@Elpezmuerto : done.
Stephen
@Stephen: Thanks!
Elpezmuerto
`boost::filesystem` is strongly recommended: it’s been accepted by the C++ standards committee as part of TR2 so it will eventually be built-in to most compilers (under `std::tr2::sys`).
Nate
A: 

Um, I don't think anything with Win32 is cross platform. If you just need to store directory names, can't you just use an array, or a vector?

Wix
A: 

The cross-platform ways of listing a directory's contents are:

On the other hand,WIN32_FIND_DATA almost certainly is not portable across different platforms (judging from the name).

stakx
<dirent.h> is not part of the C standard; it's a POSIX standard.
MSalters
You're correct. Edited accordingly.
stakx
A: 

I would use Boost.FileSystem. Untested:

#include "boost/filesystem.hpp"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

namespace bf = boost::filesystem;
typedef std::vector<bf::path> path_container;

path_container enumerate_files(const bf::path& pDirectory)
{
    path_container result;

    if (!bf::exists(pDirectory))
        return result;

    bf::directory_iterator iter(pDirectory);
    bf::directory_iterator last;

    for (; iter != last; ++iter)
        if (bf::is_regular_file(iter->status()))
            result.push_back(iter->path());

    return result;
}

int main(void)
{
    path_container c = enumerate_files("./");

    std::copy(c.begin(), c.end(),
        std::ostream_iterator<bf::path>(std::cout, "\n"));
}
GMan