views:

121

answers:

4

How to get all files in a given directory using C++ on windows?

Note:
I found methods that use dirent.h but I need a more standard way...

Thanks

+3  A: 

You have to use the FindFirstFile function (documented here). This is the standard (and preferred) way in Windows, however it is not portable. The header dirent.h you have found contains the definition of the standard POSIX functions.

For the full code look at this example: Listing the Files in a Directory

Lorenzo
+1  A: 

Use FindFirstFile and related functions. Example:

HANDLE hFind;
WIN32_FIND_DATA data;

hFind = FindFirstFile("c:\\*.*", &data);
if (hFind != INVALID_HANDLE_VALUE) {
  do {
    printf("%s\n", data.cFileName);
  } while (FindNextFile(hFind, &data));
  FindClose(hFind);
}
casablanca
-1 for using the obsolete 8-bit API.
Philipp
@Philipp: which is the obsolete *8-bit* API???
Lorenzo
@Lorenzo: The one that casablanca used, called "ANSI" by the MSDN Library (the term "8-bit" is technically correct, but seems to be used by me exclusively). It is only included for compatibility with Windows 9x. The native API is UTF-16. To use it, define `UNICODE` everywhere and replace 8-bit functions like `printf` either by generic macros (`_tprintf`) or the UTF-16 function (`_wprintf`), and use "wide" string constants with the `L` prefix or the `TEXT` macro. See your own posting for a better example (still without `UNICODE` because that should be defined via a compiler switch).
Philipp
@Philipp: now makes more sense, but if you say "8-bit API" it will hardly be interpreted as "non-UNICODE API". In my opinion it doesn't deserves a -1, as there's no real need to add complexity to a sample adding TEXT() macro and _txxx functions.
Lorenzo
@Philipp: This is an example for listing files, not about text output, and `printf` serves the purpose well here. I could have even used `MessageBox` instead of `printf`, but well, that's not the point.
casablanca
@casablanca: Yes, it's not about text output, but there are already so many examples that unnecessarily use the obsolete API that another one is not required. @Lorenzo: You don't have to add `TEXT` macros if you don't want, you can use wide strings (`L"…"`) instead. But you *must* do one of these on Windows, otherwise your program is broken.
Philipp
@Philipp: You're confusing `UNICODE` (selects Win32 API, such as `FindFirstFileA/W`) and `_UNICODE` (selects MS CRT API, such as `printf`/`wprintf`)
MSalters
@MSalters: Indeed I forgot to mention `_UNICODE`; both are required (and `NOMINMAX` and `STRICT` should also be defined). In this case I'd say that `UNICODE` is the more important switch because it selects `FindFirstFileW`.
Philipp
+7  A: 

What about the boost library: filesystem. Boost.org

domachine
+1 for Boost. You might want to link to the filesystem docs: http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm
Michael Aaron Safyan
This is hardly the "standard way" in Windows...
Lorenzo
It depends on the definition of the word "standard." If you only accept ISO standards, then there is no standard way at all. `FindFirstFile` is the accepted OS interface for listing directory entries, and Boost.Filesystem is just a wrapper around this interface on Windows. Both are de-facto standards.
Philipp
The standard on Windows is to stay as far away from the Win32 API as possible. If Boost offers a sane alternative, that's the reflex of a lot of C++ developers would be to jump at it.
jalf
@Philipp: but the user asked the standard way *in WIndows*.
Lorenzo
@Lorenzo: As I said, it depends on what you mean with "standard." The API solution is just fine: it's easy to use, flexible and doesn't introduce additional dependencies. But it's not standardized in the sense that there is an ISO standard for it.
Philipp
@jalf: Generally I favor Boost over the Windows API, but in this case the API returns more information and is fairly easy to use, so I wouldn't recommend against it unless OS independence is required.
Philipp
+1  A: 

The accepted standard for C++ is described in N1975. Your compiler might not have it yet, in which case Boost.FileSystem provides essentially the same.

MSalters