用UNICODE名称搜索文件
问题描述:
我试图在编译成功后编译这个程序,它在控制台窗口上打印程序的当前目录。 但该程序的工作是向我展示所有扩展名为.doc的文件,当我不使用宽字符串wstring()
时,它也能正常工作。所以这是我想用wstring函数编译此程序的问题。用UNICODE名称搜索文件
UPDATE:
此代码正常工作:
#define UNICODE
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <windows.h>
#include <conio.h>
using namespace std;
/*
#define UNICODE
#define _UNICODE
typedef std::string UTF8String;
*/
int SearchDirectory(std::vector<std::string> &refvecFiles,
const std::string &refcstrRootDirectory,
const std::string &refcstrExtension,
bool bSearchSubdirectories = true)
{
std::string strFilePath; // Filepath
std::string strPattern; // Pattern
std::string strExtension; // Extension
HANDLE hFile; // Handle to file
WIN32_FIND_DATA FileInformation; // File information
strPattern = refcstrRootDirectory + "\\*.*";
hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
if(hFile != INVALID_HANDLE_VALUE)
{
do
{
if(FileInformation.cFileName[0] != '.')
{
strFilePath.erase();
strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;
if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(bSearchSubdirectories)
{
// Search subdirectory
int iRC = SearchDirectory(refvecFiles,
strFilePath,
refcstrExtension,
bSearchSubdirectories);
if(iRC)
return iRC;
}
}
else
{
// Check extension
strExtension = FileInformation.cFileName;
strExtension = strExtension.substr(strExtension.rfind(".") + 1);
if(strExtension == refcstrExtension)
{
// Save filename
refvecFiles.push_back(strFilePath);
}
}
}
} while(::FindNextFile(hFile, &FileInformation) == TRUE);
// Close handle
::FindClose(hFile);
DWORD dwError = ::GetLastError();
if(dwError != ERROR_NO_MORE_FILES)
return dwError;
}
return 0;
}
// Prototype for conversion functions
std::wstring StringToWString(const std::string& s);
std::string WStringToString(const std::wstring& s);
std::wstring StringToWString(const std::string& s)
{
std::wstring temp(s.length(),L' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
std::string WStringToString(const std::wstring& s)
{
std::string temp(s.length(), ' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
int main()
{
int iRC = 0;
std::vector<std::string > vecAviFiles;
std::vector<std::string > vecTxtFiles;
// Search 'c:' for '.avi' files including subdirectories
iRC = SearchDirectory(vecAviFiles, "c:", "doc");
if(iRC)
{
std::cout << "Error " << iRC << std::endl;
return -1;
}
// Print results
for(std::vector<std::wstring>::iterator iterAvi = vecAviFiles.begin(); iterAvi != vecAviFiles.end(); ++iterAvi)
std::wcout << *iterAvi << std::endl;
}
不工作代码:
#include <string>
#include <vector>
#include <iostream>
#include <windows.h>
#include <conio.h>
int SearchDirectory(std::vector<std::wstring> &refvecFiles,
const std::wstring &refcstrRootDirectory,
const std::wstring &refcstrExtension,
bool bSearchSubdirectories = true)
{
std::wstring strFilePath; // Filepath
std::wstring strPattern; // Pattern
std::wstring strExtension; // Extension
HANDLE hFile; // Handle to file
WIN32_FIND_DATAW FileInformation; // File information
strPattern = refcstrRootDirectory + L"\\*.*";
hFile = ::FindFirstFileW(strPattern.c_str(), &FileInformation);
if(hFile != INVALID_HANDLE_VALUE)
{
do
{
if(FileInformation.cFileName[0] != '.')
{
strFilePath.erase();
strFilePath = refcstrRootDirectory + L"\\" + FileInformation.cFileName;
if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(bSearchSubdirectories)
{
// Search subdirectory
int iRC = SearchDirectory(refvecFiles,
strFilePath,
refcstrExtension,
bSearchSubdirectories);
if(iRC)
return iRC;
}
}
else
{
// Check extension
strExtension = FileInformation.cFileName;
strExtension = strExtension.substr(strExtension.rfind(L".") + 1);
if(strExtension == refcstrExtension)
{
// Save filename
refvecFiles.push_back(strFilePath);
}
}
}
} while(::FindNextFileW(hFile, &FileInformation) == TRUE);
// Close handle
::FindClose(hFile);
DWORD dwError = ::GetLastError();
if(dwError != ERROR_NO_MORE_FILES)
return dwError;
}
return 0;
}
int main()
{
int iRC = 0;
std::vector<std::wstring> vecAviFiles;
// Search 'c:' for '.avi' files including subdirectories
iRC = SearchDirectory(vecAviFiles, L"c:", L"doc");
if(iRC)
{
std::cout << "Error " << iRC << std::endl;
return -1;
}
// Print results
for(std::vector<std::wstring>::iterator iterAvi = vecAviFiles.begin(); iterAvi != vecAviFiles.end(); ++iterAvi)
std::wcout << *iterAvi << std::endl;
}
什么我想知道的是为什么第二个程序不起作用?
答
你在做错了。
考虑strPattern = refcstrRootDirectory + L"\\*.*";
。那*.*
是有原因的。这是您指定要查找的文件模式的位置。如果您想寻找*.doc
文件,这样说:strPattern = refcstrRootDirectory + L"\\*." + refcstrExtension;
此外,一些风格笔记:
- 删除该类型的前缀。这是一种用于弱类型语言的惯例; C++是强类型的。
- 定义的变量,你需要他们,而不是早先:
std::wstring Pattern = RootDirectory + L"\\*.*";
HFILE File = ::FindFirstFileW(Pattern.c_str(), &FileInformation);
- 没有必要删除一个字符串,如果你分配一个新的值。例如。这工作正常。
FilePath = RootDirectory + L"\\" + FileInformation.cFileName;
- 检查一下这个是干什么的文件没有扩展。
- 你正在泄漏文件句柄
if(iRC) return iRC;
。 (C++对象会自动清理,但这是一个C API)。
那你的错误是什么? – m0skit0 2012-02-23 13:30:13
首先: X:\ C++ \ boost迭代器\ bin \ Debug \ 进程返回0(0x0)执行时间:12.165秒 按任意键继续。 也是这个进程的当前目录 其次: 我会将.doc改为另一个扩展,而不是这个问题 问题是我无法获得带有.doc文件的路径(或者转换器) 延期。 – pourjour 2012-02-23 13:35:58
你的代码完全适合我。我唯一的建议是在这里使用不区分大小写的字符串比较:strExtension == refcstrExtension – 2012-02-23 13:42:47