I want to list all files of the current directory, so I have this code :
int WLoader::listdir(void)
{
WIN32_FIND_DATA data;
std::wstring path(L"*");
std::wstring *name;
HANDLE hFile = FindFirstFile(path.c_str(), &data);
if (hFile == INVALID_HANDLE_VALUE)
return (-1);
while(FindNextFile(hFile, &data) != 0 || GetLastError() != ERROR_NO_MORE_FILES)
{
std::cout << data.cFileName << std::endl;
}
return (0);
}
For unknown reasons, my program is displaying this result :
0029F29C
0029F29C
0029F29C
0029F29C
0029F29C
0029F29C
Can someone help me please?
The WIN32_FIND_DATA
structure's member cFileName
is a TCHAR[N]
, and TCHAR
is a Windows type alias that maps either to char
or wchar_t
. Problem is, you don't know which one it will be when you write your code.
Depending on your build settings, you either have a char*
, or a wchar_t*
; one should be used with std::cout
and the other must be used with std::wcout
. But which one do you use?!
Fortunately, there's a macro to find out which is in use when you compile:
while(FindNextFile(hFile, &data) != 0 || GetLastError() != ERROR_NO_MORE_FILES) {
#ifdef UNICODE
std::wcout << data.cFileName << std::endl;
#else
std::cout << data.cFileName << std::endl;
#endif
}
You're going to find the same problem if you try to assign the filename to a std::string
/std::wstring
. That's what you get for using the Windows API. :)
One way around this is to define macros for the output stream and for strings.
So, somewhere at the top of your program:
#ifdef UNICODE
#define STDCOUT std::wcout
#define STDSTR std::wstring
#else
#define STDCOUT std::cout
#define STDSTR std::string
#endif
Then in your function, all you need is:
while(FindNextFile(hFile, &data) != 0 || GetLastError() != ERROR_NO_MORE_FILES) {
STDCOUT << data.cFileName << std::endl;
}
and you can use STDSTR
elsewhere.
Something to consider.