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

发布于 2025-01-04 03:46:18 字数 4316 浏览 5 评论 0原文

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

#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:\\Ím.txt";

至:
string fileName = "C:\\??.txt";

但徒劳。

我怎样才能复制这个文件?

I got this source code from somewhere on the Net. It searches for files on the hard disk and prints out the path of the files:

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

The problem is that when it finds a filename with Arabic text, it doesn't display it correctly; It just shows "?????????????????????". I need the file path to send to a server. Is there anyway to solve the problem?

UPDATE:
I have revised the code.

The new code is as follows:

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

This code compiles, but I get this error:

ErrorErrorstd::exception

Also, the copying process fails.

I tried to change this line:
string fileName = "C:\\حم.txt";

to:
string fileName = "C:\\??.txt";

but in vain.

How can I copy this file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

戒ㄋ 2025-01-11 03:46:18

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

如果您需要编写可移植代码,则可能需要将代码划分为可移植部分和不可移植部分。当调用实际的文件 API 时,您将从更明智的编码(UTF-8?)转换为特定于平台的文件名(对于 Windows,PWSTR;您可以使用 MultiByteToWideChar 来完成此操作CP_UTF8 作为源代码页)。

If your OS is Windows, using 8-bit characters to name files is a bad idea; it will restrict you to the so-called "ANSI code page" (itself something of a misnomer). Define UNICODE and _UNICODE and use Windows APIs that accept PWSTR. This will allow you to have unicode filenames.

If you need to write portable code, you may need to partition your code into portable and non-portable parts. When calling the actual file APIs you would then convert from a saner encoding (UTF-8?) to the platform-specific filename (PWSTR in the case of Windows; you can do this with MultiByteToWideChar and CP_UTF8 as the source code page).

时光倒影 2025-01-11 03:46:18

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

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

You're "just a beginner", so I strongly suggest this: download Boost and use Boost.Filesystem. It has a class boost::filesystem::path that represents a filename. It's all you should use for dealing with filenames. Use the Boost.Filesystem functions for searching for files, and use the boost::filesystem::path object and the special iostreams in Boost.Filesystem to open those files.

Printing Unicode-encoded strings to the console window is... not easily done in Windows.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文