I was writing this function to search a file inside the computer but i encountered a problem: When I read the files that have been found during the search(using the for cycle inside the main() ) the directory are broken. With some debugging I saw that when pushed inside the file_found vector,they are intact,but when i read the vector in the main they're like overlapped and with a "*" at the end.How can i fix this?
#include <stdio.h>
#include <vector>
#include <Windows.h>
int SearchForFileW(WCHAR * fileName,LPWSTR dir,std::vector<LPWSTR>& file_found)
{
WIN32_FIND_DATAW winFindDataFirst;
HANDLE hFile = FindFirstFileW(dir,&winFindDataFirst);
if (!wcscmp(winFindDataFirst.cFileName,fileName))
{
wchar_t tmp[MAX_PATH] = { 0 };
_snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
wcscpy(dir, tmp);
wcscat(dir, winFindDataFirst.cFileName);
file_found.push_back(dir);
}
while (true)
{
if (FindNextFileW(hFile, &winFindDataFirst) == 0)
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
return 0;
}
else
{
return -1;
}
}
if (!wcscmp(winFindDataFirst.cFileName, L".") ||
!wcscmp(winFindDataFirst.cFileName, L".."))
{
continue;
}
else if(!wcscmp(winFindDataFirst.cFileName,fileName))
{
wchar_t tmp[MAX_PATH] = { 0 };
_snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
wcscpy(dir, tmp);
wcscat(dir, winFindDataFirst.cFileName);
file_found.push_back(dir);
}
if ((winFindDataFirst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
wchar_t tmp[MAX_PATH] = { 0 };
_snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
wcscpy(dir, tmp);
wcscat(dir, winFindDataFirst.cFileName);
wcscat(dir, L"\\*");
SearchForFileW(fileName, dir,file_found);
_snwprintf(tmp, wcslen(dir) - (wcslen(winFindDataFirst.cFileName) + wcslen(L"\\*")), dir);
wcscpy(dir, tmp);
wcscat(dir, L"*");
}
else
{
printf("File:-------%S\n\n", winFindDataFirst.cFileName);
}
}
return 0;
}
int main()
{
std::vector<LPWSTR> file;
WCHAR dirBuff[MAX_PATH] = {0};
wcscpy(dirBuff,L"c:\\*");
SearchForFileW(L"MyFile.txt", dirBuff,file);
if (file.size() == 0)
{
printf("No file found");
}
else
{
for (int i = 0; i < file.size(); i++)
{
printf("File found at: %S\n", file.at(i));
}
}
}
A
std::vector<LPWSTR>
is astd::vector<wchar_t*>
(sinceLPWSTR
is a typedef forwchar_t*
).Now, having a vector of raw owning pointers is very fragile. You can have a vector of raw observing pointers, and you must be sure that the strings pointed to are still allocated (kind of "live") when you refer them using those pointers. And that is not your case.
The simplest thing to do is to just use C++ string classes like
std::wstring
instead of the rawwchar_t*
pointers.So, you can substitute your
vector<LPWSTR>
with avector<wstring>
. In this case, the lifetime of the strings will be automatically managed by the C++ compiler and the STL implementation: you can focus on the core of your algorithm, not on bug-prone string memory management implementation details.