2015-12-02 197 views
1

我正在用C++編寫程序。我試圖獲取程序可執行文件所在文件夾中的所有文件,並將它們存儲在一個向量中。我被告知下面的代碼應該可以工作,但FindFirstFile操作只能找到一個文件(它應該搜索的文件夾的名稱)。我如何更改代碼,以便它正確地查看文件夾?如何獲取目錄中的所有文件名?

std::vector<char*> fileArray; 

//Get location of program executable 
HMODULE hModule = GetModuleHandleW(NULL); 
WCHAR path[MAX_PATH]; 
GetModuleFileNameW(hModule, path, MAX_PATH); 

//Remove the executable file name from 'path' so that it refers to the folder instead 
PathCchRemoveFileSpec(path, sizeof(path)); 

//This code should find the first file in the executable folder, but it fails 
//Instead, it obtains the name of the folder that it is searching 
WIN32_FIND_DATA ffd; 
HANDLE hFind = INVALID_HANDLE_VALUE; 
hFind = FindFirstFile(path, &ffd); 

do 
{ 
    //The name of the folder is pushed onto the array because of the previous code's mistake 
    //e.g. If the folder is "C:\\MyFolder", it stores "MyFolder" 
    fileArray.push_back(ffd.cFileName); //Disclaimer: This line of code won't add the file name properly (I'll get to fixing it later), but that's not relevant to the question 
} while (FindNextFile(hFind, &ffd) != 0); //This line fails to find anymore files 
+2

試圖把\\ *在路徑結束 – immibis

回答

3

有人告訴我下面的代碼應該工作

你被告知錯了,因爲你的代碼都是嚴重破損。

FindFirstFile操作僅查找一個文件(應該搜索的文件夾的名稱)。

您只傳遞文件夾路徑到FindFirstFile(),因此只有一個條目會被報告,描述文件夾本身。您需要做的是將**.*通配符附加到路徑的末尾,然後FindFirstFile()/FindNextFile()將枚舉文件夾內的文件和子文件夾。

除此之外,代碼還有其他一些問題。

即使枚舉正在工作,您也沒有區分文件和子文件夾。

您正在向PathCchRemoveFileSpec()的第二個參數傳遞一個錯誤值。您正在傳遞一個字節計數,但它預計會有字符而不是計數。

在進入循環之前,您沒有檢查FindFirstFile()是否失敗,並且在循環結束後沒有調用FindClose()

最後,你的代碼甚至不會按原樣編譯。您的vector正存儲char*值,但爲了通過一個WCHAR[]FindFirstFile()UNICODE必須定義,這意味着FindFirstFile()將映射到FindFirstFileW()WIN32_FIND_DATA將映射到WIN32_FIND_DATAW,因此cFileName字段將是一個WCHAR[]。編譯器將不允許WCHAR[](或WCHAR*)被分配到一個char*

嘗試一些更喜歡這個代替:?

std::vector<std::wstring> fileArray; 

//Get location of program executable 
WCHAR path[MAX_PATH+1] = {0}; 
GetModuleFileNameW(NULL, path, MAX_PATH); 

//Remove the executable file name from 'path' so that it refers to the folder instead 
PathCchRemoveFileSpec(path, MAX_PATH); 

// append a wildcard to the path 
PathCchAppend(path, MAX_PATH, L"*.*"); 

WIN32_FIND_DATAW ffd; 
HANDLE hFind = FindFirstFileW(path, &ffd); 
if (hFile != INVALID_HANDLE_VALUE) 
{ 
    do 
    { 
     if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) 
      fileArray.push_back(ffd.cFileName); 
    } 
    while (FindNextFileW(hFind, &ffd)); 
    FindClose(hFind); 
} 
+0

此代碼肯定獲得所有的文件準確,但我怎麼能得到它們在char *形式而不是wstring? – Ben

+1

如果你想讓你的程序正常工作,不要。(如果其中一個文件名包含一個字符那是不是在當前代碼頁?) –

+0

@Ben:Harry是對的,你真的不應該安裝你的代碼。Windows是一個Unicode操作系統,而NTFS使用Unicode fi lenames。你應該使用Unicode的一切。這就是說,如果你真的需要'char'格式的文件名而不是'WCHAR',可以使用'WideCharToMultiByte()'將文件名從'WCHAR'轉換爲'char',否則使用'FindFirstFileA()'/ 'FindNextFileA()'而不是'FindFirstFileW()'/'FindNextFileW()'... –

相關問題