2015-12-02 47 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()'... –

相关问题