I wrote a simple recursive file search by mask. With English characters, everything works fine, but as soon as the program meets Russian, it sends garbage to the buffer and the function crashes. I tried to take the code from this site (from a similar question), but it also does not work with Russian characters. Code example:

typedef std::basic_string<TCHAR> StdString; 

function to search for files in the current folder

 void ScanFolder(const StdString & folder, const StdString & mask) { WIN32_FIND_DATA find_data; HANDLE find_handle = FindFirstFile((folder + mask).c_str(), &find_data); if (INVALID_HANDLE_VALUE == find_handle) { return; } else { do { cout << folder << find_data.cFileName << endl; } while (FindNextFile(find_handle, &find_data)); FindClose(find_handle); } 

and recursive function for searching folders and calling the first function

 void FindFileRecursive(StdString start_path, const StdString & mask) { start_path = rtrim(start_path) + _T("\\"); ScanFolder(start_path, mask); WIN32_FIND_DATA folder_data; HANDLE folder_find = FindFirstFileEx ( (start_path + _T("*")).c_str() , FindExInfoStandard , &folder_data , FindExSearchLimitToDirectories // поиск папок , NULL , FIND_FIRST_EX_LARGE_FETCH ); if (INVALID_HANDLE_VALUE == folder_find) { return; } else { do { if (FILE_ATTRIBUTE_DIRECTORY & folder_data.dwFileAttributes) { if (strcmp(folder_data.cFileName, ".") && strcmp(folder_data.cFileName, "..")) { FindFileRecursive( start_path + folder_data.cFileName, mask) } } } while (FindNextFile(folder_find, &folder_data)); FindClose(folder_find); } } 

Error due to the fact that negative values ​​(Russian letters) are passed to the function. How to pass a string as an argument in this case?

  • 2
    In the project settings, what parameters _UNICODE / _MBCS are set? Instead of strcmp try using _tcscmp . And in general, do not mix C and C ++. - Alexander Petrov

1 answer 1

I suspect that you have disabled UNICODE. The Windows kernel works with unicode. WinAPI for chars converts input wchars to chars, calls kernel functions, gets the result in wchars and converts them to chars again. Thus, your function will be intensively engaged in an onanism: allocate / free memory for intermediate results and drive the chars back and forth to the wchars.

But you probably this is not enough, and decided to increase the amount of onanism to attract more thongs. Which also with each sneeze is engaged in the allocation / release of memory, and perhaps also all sorts of char-s / wchar conversions. The misunderstanding of Russian characters lies precisely in them. Just WinAPI works without problems.

Take one buffer of sufficient volume and write one function. Everything will work.

 void ScanFolder(LPTSTR pFolder, LPCTSTR pMask) { size_t nLen = _tcslen(pFolder); pFolder[nLen++] = '\\'; WIN32_FIND_DATA fd; HANDLE hf; // Файлы по маске _tcscpy(pFolder + nLen, pMask); hf = FindFirstFile(pFolder, &fd); if ( hf != INVALID_HANDLE_VALUE ) { do { if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { // TODO: } } while( FindNextFile(hf, &fd) ); FindClose(hf); } // Дочерние папки _tcscpy(pFolder + nLen, _T("*.*")); hf = FindFirstFile(pFolder, &fd); if ( hf != INVALID_HANDLE_VALUE ) { do { if ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if ( _tcscmp(fd.cFileName, _T(".")) && _tcscmp(fd.cFileName, _T("..")) ) { if ( fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) { // TODO: Это ссылка, решаешь сам лезь туда или нет } else { _tcscpy(pFolder + nLen, fd.cFileName); ScanFolder(pFolder, pMask); } } } } while( FindNextFile(hf, &fd) ); FindClose(hf); } pFolder[--nLen] = 0; } 

For the ANSI version, the buffer (maximum path length) is MAX_PATH. For UNICODE 32767 characters. But to use the "long path" it must begin with the four-character prefix "\\\\?\\" . For example, L"\\\\?\\C:\\и так далее" . L"\\\\?\\C:\\и так далее"