1

I want to get a list of all files in particular directory.For that |I use the following code

void GetFileListing(std::list<std::string>& listing, std::string directory, std::string fileFilter, bool recursively=true) { //check if directory exits: DWORD attribs = ::GetFileAttributesA(directory.c_str()); if (attribs == INVALID_FILE_ATTRIBUTES || !(attribs & FILE_ATTRIBUTE_DIRECTORY)) { return ; } // If we are going to recurse over all the subdirectories, first of all // get all the files that are in this directory that match the filter if (recursively) GetFileListing(listing, directory, fileFilter, false); directory += "\\"; WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; // Setup the filter according to whether we are getting the directories // or just the files std::string filter = directory + (recursively ? "*" : fileFilter); // Find the first file in the directory. hFind = FindFirstFile(LPCWSTR(filter.c_str()), &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); if (dwError!=ERROR_FILE_NOT_FOUND) { std::cout << "Invalid file handle for filter "<<filter<<". Error is " << GetLastError() << std::endl; } } else { // Add the first file found to the list if (!recursively) { wstring wFindFileData = FindFileData.cFileName; listing.push_back(directory + std::string(wFindFileData.begin(),wFindFileData.end())); } // List all the other files in the directory. while (FindNextFile(hFind, &FindFileData) != 0) { if (!recursively) { wstring wFindFileData = FindFileData.cFileName; listing.push_back(directory + std::string(wFindFileData.begin(),wFindFileData.end())); } else { // If we found a directory then recurse into it if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0 && FindFileData.cFileName[0]!='.') { wstring wFindFileData = FindFileData.cFileName; GetFileListing(listing, directory + std::string(wFindFileData.begin(),wFindFileData.end()), fileFilter); } } } DWORD dwError = GetLastError(); FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { std::cout << "FindNextFile error. Error is "<< dwError << std::endl; } } } int main(int argc, char *argv[]) { if(argc < 2) return 0; std::list<std::string> listing; GetFileListing(listing, argv[1], "*"); for(std::list<std::string>::iterator it = listing.begin(); it!=listing.end();++it) { std::cout << *it << std::endl; } } 

In args I transfer a valid existing directory .Actualy args[1] becomes "C:\dir". But I don`t get a desired list,instead of it the following error occurs :

Invalid file handle for filter C:\dir\*. Error is 123 

I can`t understand what is wrong here?

1

1 Answer 1

2

You're mixing ANSI with UNICODE and even worse, casting a char* to wchar_t*.

std::string filter; // ... LPCWSTR(filter.c_str()) // this does not work and causes the error! 

If you require your function to use std::string, keep it entirely ANSI (use FindFirstFileA, FindNextFileA and WIN32_FIND_DATAA). Otherwise work with std::wstring instead and use the functions/structures ending with W instead of A.

The windows headers define FindFirstFile as FindFirstFileW if UNICODE is defined and FindFirstFileA otherwise. So for a generic solution, typedef a std::basic_string<TCHAR> and use that as the string type. That way it uses std::wstring when UNICODE is defined and std::string otherwise.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.