14

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

qwe
  • 141
  • 1
  • 1
  • 3
  • 2
    Actually, the functions in dirent.h are the more standard (POSIX) way. –  Jul 04 '10 at 21:12
  • 3
    But the file is not included in VC++ 2008 – qwe Jul 04 '10 at 21:14
  • 1
    @Neil: POSIX is not part of the standard library and it is not well supported by the most used C/C++ compiler (MSVC) of the most used operating system (Windows). – lornova Jul 04 '10 at 21:18
  • 3
    @Lorenzo POSIX is a standard - Windows isn't. But from your other posts here I don't see much point in arguing the point. –  Jul 04 '10 at 21:24
  • 4
    It's completely irrelevant whether POSIX is more standard than Windows or not. The original question is clearly related to Windows, and thus talking about `dirent.h` makes absolutely no sense and is not helpful. – Philipp Jul 04 '10 at 21:45
  • @Phillip The questioner introduced dirent.h, not me. And I use it in my Windows code all the time. –  Jul 04 '10 at 22:12
  • This is a duplicate of: http://stackoverflow.com/questions/2314542/listing-directory-contents-using-c-and-windows/2315808#2315808 – NTDLS Aug 25 '16 at 17:15

4 Answers4

30

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
  • 69,683
  • 7
  • 133
  • 150
  • @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 Jul 04 '10 at 22:04
  • 7
    @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. – lornova Jul 04 '10 at 22:22
  • 1
    @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 Jul 04 '10 at 23:15
  • 1
    @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 Jul 05 '10 at 07:28
  • 1
    @Philipp: You're confusing `UNICODE` (selects Win32 API, such as `FindFirstFileA/W`) and `_UNICODE` (selects MS CRT API, such as `printf`/`wprintf`) – MSalters Jul 05 '10 at 13:17
  • @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 Jul 05 '10 at 13:28
  • @casablanca: You could add #include in the begining. But nice answer anyway – Jake OPJ Nov 01 '17 at 00:43
10

What about the boost library: filesystem. Boost.org

domachine
  • 1,119
  • 1
  • 12
  • 20
  • 4
    +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 Jul 04 '10 at 21:56
  • 1
    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 Jul 04 '10 at 22:07
  • 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 Jul 04 '10 at 22:17
  • @Philipp: but the user asked the standard way *in WIndows*. – lornova Jul 04 '10 at 23:18
  • @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 Jul 05 '10 at 07:25
  • @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 Jul 05 '10 at 07:29
5

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

lornova
  • 6,667
  • 9
  • 47
  • 74
4

The accepted standard for C++ is described in N1975 ISO/IEC TS 18822:2015, latest draft is N4100. Your compiler might not have it yet, in which case Boost.FileSystem provides essentially the same.

MSalters
  • 173,980
  • 10
  • 155
  • 350