0

コンパイルが成功したら、このプログラムをコンパイルしようとしましたが、コンソール ウィンドウにプログラムの現在のディレクトリが表示されます。しかし、プログラムの仕事は、拡張子が .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;
}

私が知りたいのは、なぜ 2 番目のプログラムが機能しないのかということです。

4

1 に答える 1

0

You're Doing It Wrong™.

を検討してください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 です)。
于 2012-02-24T10:27:38.113 に答える