Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

You are using std::cout to output a wide-character string. Use std::wcout instead.

I expect you have a Unicode/ANSI mismatch. To print a Unicode string, use std::wcout

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top