如何在 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:\\Í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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的操作系统是 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 acceptPWSTR
. 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 withMultiByteToWideChar
andCP_UTF8
as the source code page).您“只是一个初学者”,所以我强烈建议:下载 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 theboost::filesystem::path
object and the specialiostreams
in Boost.Filesystem to open those files.Printing Unicode-encoded strings to the console window is... not easily done in Windows.