使用UNICODE名称搜索文件

时间:2012-02-23 13:28:38

标签: c++ file search unicode wstring

我试图在编译成功后编译该程序,它在控制台窗口打印程序的当前目录。 但该程序的工作是向我展示扩展名为.doc的所有文件,当我不使用宽字符串wstring()时,它也能正常工作。所以这是我想用wstring编译这个程序的问题功能。

更新

此代码正常工作:

#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;
}

我想知道的是为什么第二个程序不起作用?

1 个答案:

答案 0 :(得分:0)

你做错了。

考虑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)。