如何在Windows中处理带有阿拉伯文本的文件名?

时间:2012-02-11 01:19:56

标签: c++ filenames handle arabic

我从网上的某个地方获得了这个源代码。它搜索硬盘上的文件并打印出文件的路径:

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

但是徒劳无功。

如何复制此文件?

2 个答案:

答案 0 :(得分:2)

如果您的操作系统是Windows,使用8位字符命名文件是个坏主意;它会限制你所谓的“ANSI代码页”(本身就是用词不当)。定义UNICODE_UNICODE并使用接受PWSTR的Windows API。这将允许您拥有unicode文件名。

如果您需要编写可移植代码,则可能需要将代码分区为便携式和非便携式部件。在调用实际文件API时,您将从saner编码(UTF-8?)转换为特定于平台的文件名(在{J}的情况下为PWSTR;您可以使用MultiByteToWideChar和{CP_UTF8执行此操作{1}}作为源代码页。)

答案 1 :(得分:0)

您只是“初学者”,所以我强烈建议:下载Boost并使用Boost.Filesystem。它有一个表示文件名的类boost::filesystem::path。这就是你应该用来处理文件名的全部内容。使用Boost.Filesystem函数搜索文件,并使用boost::filesystem::path对象和Boost.Filesystem中的特殊iostreams来打开这些文件。

将Unicode编码的字符串打印到控制台窗口......在Windows中不容易完成。