Список каталогов в C ++ под Windows - PullRequest
1 голос
/ 02 января 2012

Я хочу перечислить все файлы текущего каталога, поэтому у меня есть этот код:

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);
}

По неизвестным причинам моя программа отображает этот результат:

0029F29C
0029F29C
0029F29C
0029F29C
0029F29C
0029F29C

Можеткто-нибудь, помогите мне, пожалуйста?

Ответы [ 3 ]

4 голосов
/ 02 января 2012

Член структуры WIN32_FIND_DATA cFileName является TCHAR[N], а TCHAR - псевдонимом типа Windows, который отображается либо на char, либо на wchar_t. Проблема в том, что вы не знаете, какой из них будет , когда вы будете писать свой код.

В зависимости от настроек вашей сборки, у вас будет либо char*, либо wchar_t*;один должен использоваться с std::cout, а другой должен использоваться с std::wcout.Но какой из них вы используете?!

К счастью, есть макрос для определения, который используется при компиляции:

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
}

Вы найдете ту же проблему, если выПопробуйте назначить имя файла для std::string / std::wstring.Вот что вы получаете за использование Windows API.:)


Одним из способов решения этой проблемы является определение макросов для выходного потока и для строк.

Итак, где-то вверху вашей программы:

#ifdef UNICODE
#define STDCOUT std::wcout
#define STDSTR  std::wstring
#else
#define STDCOUT std::cout
#define STDSTR  std::string
#endif

Тогда в вашей функции все, что вам нужно:

while(FindNextFile(hFile, &data) != 0 || GetLastError() != ERROR_NO_MORE_FILES) {
   STDCOUT << data.cFileName << std::endl;
}

, и вы можете использовать STDSTR в другом месте.

Что-то рассмотреть.

3 голосов
/ 02 января 2012

Вы используете std::cout для вывода строки широких символов. Вместо этого используйте std::wcout.

1 голос
/ 02 января 2012

Я ожидаю, что у вас есть несоответствие Unicode / ANSI.Чтобы напечатать строку Unicode, используйте std::wcout

...