我想列出当前目录的所有文件,所以我有这样的代码:
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
有人能帮助我吗?
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
。
有些事情要考虑。
你正在使用std::cout
来输出一个宽字符的字符串。 改用std::wcout
。
我希望你有一个Unicode / ANSI不匹配。 要打印一个Unicode字符串,请使用std::wcout