搜索具有UNICODE名称的文件

Search files with UNICODE names

本文关键字:文件 UNICODE 搜索      更新时间:2023-10-16

编译成功后,我尝试编译这个程序,它会在控制台窗口中打印程序的当前目录。但这个程序的工作是向我展示所有扩展名为.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;
}

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

你做错了™.

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