2012-02-11 11 views
-2

私はこのソースコードをネット上のどこかから入手しました。これは、ハードディスク上のファイルを検索し、ファイルのパスを出力します:Windowsでアラビア語のファイル名を扱うにはどうすればよいですか?

#include <string> 
#include <vector> 
#include <iostream> 

#include <windows.h> 
#include <conio.h> 



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


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, "d:", "doc"); 
    if(iRC) 
    { 
    std::cout << "Error " << iRC << std::endl; 
    return -1; 
    } 

    // Print results 
    for(std::vector<std::string>::iterator iterAvi = vecAviFiles.begin(); 
     iterAvi != vecAviFiles.end(); 
     ++iterAvi) 
    std::cout << *iterAvi << std::endl; 

    // Search 'c:\textfiles' for '.txt' files excluding subdirectories 
    /* 
    iRC = SearchDirectory(vecTxtFiles, "c:\\textfiles", "txt", false); 
    if(iRC) 
    { 
    std::cout << "Error " << iRC << std::endl; 
    return -1; 
    } 

    // Print results 
    for(std::vector<std::string>::iterator iterTxt = vecTxtFiles.begin(); 
     iterTxt != vecTxtFiles.end(); 
     ++iterTxt) 
    std::cout << *iterTxt << std::endl; 

    // Wait for keystroke 
    _getch(); 
    */ 

    return 0; 
} 

問題は、それがアラビア語のテキストとファイル名を見つけたとき、それを正しく表示されないということです。それはちょうど"?????????????????????"を示しています。私はサーバーに送るファイルパスが必要です。とにかく問題を解決するには?

更新日: 私はコードを改訂しました。次のように

新しいコードは次のとおりです。

#include <boost/filesystem.hpp> 
namespace bf = boost::filesystem; 
#include <string> 
#include <iostream> 
using namespace std; 
string e_string = "Error"; 
int main() 
{ 
    string fileName = "C:\\حم.txt"; 
    string destination = "D:\\log.txt" ; 
    bf::path fileCopied(fileName); 
    bf::path fileCopiedDestination (destination); 
    if (!bf::exists(fileCopied)) 
    { 
     cerr << e_string; 
    } 
    if (!bf::exists(fileCopiedDestination)) 
     { 
     cerr << e_string; 
    } 
    try 
    { 
     bf::copy_file(fileCopied,fileCopiedDestination); 
    } 
    catch(std::exception e) 
    { 
     cout << e.what(); 
    } 
} 

このコードはコンパイルが、私はこのエラーを取得:

ErrorErrorstd::exception 

また、コピー処理は失敗します。
string fileName = "C:\\??.txt";

無駄だった:
string fileName = "C:\\حم.txt";

へ:

私はこの行を変更しようとしました。

このファイルをコピーするにはどうすればよいですか?

+0

アラビアファイル名原因となる問題 – pourjour

答えて

0

あなたは「初心者」なので、私は強くこのことをお勧めします:Boostをダウンロードし、Boost.Filesystemを使用してください。ファイル名を表すクラスboost::filesystem::pathがあります。ファイル名を扱うために使うべきことはすべてです。 Boost.Filesystem関数を使用してファイルを検索し、boost::filesystem::pathオブジェクトとBoost.Filesystem内のiostreams特殊ファイルを使用してそれらのファイルを開きます。

ユニコードでエンコードされた文字列をコンソールウィンドウに表示することは、Windowsでは簡単に行えません。私は、文字列を取得し、別の関数に渡す場合はアラビアfilname を検索する必要が

+0

私はUnicode文字を印刷する必要はありませんが、この種のファイル名を別の場所にコピーするためにablilityを取得したいですCopyFileは役に立ちません これを解決するためには問題? – pourjour

+0

@ user1203062: 'filesystem :: copy_file'はどうやって助けになりませんか?ファイルをコピーします。ファイルの名前を変更することを話しているのであれば、それは 'filesystem :: rename'です。 –

+0

windows.h APIのCopyFileメンバー関数についてお話しました このAPIがアラビア語ファイルを処理できない問題 GetLastERROR()を見ると、ファイル名にアラビア語のテキストを含むファイルをコピーできません。存在しません どうすればそのようなファイルにできますか? – pourjour

2

OSがWindowsの場合、8ビット文字を使用してファイル名を付けるのは悪い考えです。それはあなたをいわゆる "ANSIコードページ"(それ自体は誤称の何か)に制限します。 UNICODE_UNICODEを定義し、PWSTRを受け入れるWindows APIを使用します。これにより、ユニコードのファイル名を持つことができます。

移植性のあるコードを記述する必要がある場合は、コードを移植性の高いポータブルな部分に分割する必要があります。実際のファイルAPIを呼び出すときには、サマーエンコーディング(UTF-8?)からプラットフォーム固有のファイル名(Windowsの場合はPWSTR)に変換します。ソースコードページとしてMultiByteToWideCharCP_UTF8でこれを行うことができます。

+0

である私はちょうど初心者 だから私はこのコードに変更する必要があります何を明確に理解していませんUTF-8を使用してください。 – pourjour

+0

@ user1203062 - "Windowsのやり方"はどこでも 'WCHAR'を使うことです。 UTF-8の提案は、移植可能なコードを記述する必要がある場合のみです。 Win32呼び出しを使用しているので、移植性について気にしないと思う追加のコードで質問を編集したので、私の提案は単に#define UNICODE'/'#define _UNICODE'を使用し、代わりに' wstring'を使用することです。 'string'。 – asveikau

+0

は問題がどこであってもコンパイルされません – pourjour

関連する問題