在C ++ Windows中打开utf8编码的文件名 [英] Open utf8 encoded filename in c++ Windows
问题描述
考虑以下代码:
#include <iostream>
#include <boost\locale.hpp>
#include <Windows.h>
#include <fstream>
std::string ToUtf8(std::wstring str)
{
std::string ret;
int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
ret.resize(len);
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len, NULL, NULL);
}
return ret;
}
int main()
{
std::wstring wfilename = L"D://Private//Test//एउटा फोल्दर//भित्रको फाईल.txt";
std::string utf8path = ToUtf8(wfilename );
std::ifstream iFileStream(utf8path , std::ifstream::in | std::ifstream::binary);
if(iFileStream.is_open())
{
std::cout << "Opened the File\n";
//Do the work here.
}
else
{
std::cout << "Cannot Opened the file\n";
}
return 0;
}
如果我正在运行文件,则无法打开文件因此进入 else
块。即使使用 boost :: locale :: conv :: from_utf(utf8path, utf_8)
代替 utf8path
也不工作。如果我考虑使用 wifstream
并使用 wfilename
作为其参数,则该代码有效,但我不想使用 wifstream
。有什么方法可以打开名称为 utf8
编码的文件?我正在使用 Visual Studio 2010
。
If I am running the file, I cannot open the file thus entering into the else
block. Even using boost::locale::conv::from_utf(utf8path ,"utf_8")
instead of utf8path
doesn't work. The code works if I consider using wifstream
and using wfilename
as its parameter, but I don' want to use wifstream
. Is there any way to open the file with its name utf8
encoded? I am using Visual Studio 2010
.
推荐答案
在Windows上,您必须使用8位ANSI(并且必须匹配用户的语言环境)或UTF16作为文件名,没有其他选项可用。您可以在主代码中继续使用 string
和UTF8,但是在打开文件时必须将UTF8文件名转换为UTF16。效率较低,但这是您需要做的。
On Windows, you MUST use 8bit ANSI (and it must match the user's locale) or UTF16 for filenames, there is no other option available. You can keep using string
and UTF8 in your main code, but you will have to convert UTF8 filenames to UTF16 when you are opening files. Less efficient, but that is what you need to do.
幸运的是,VC ++的 std :: ifstream
和 std :: ofstream
的构造函数和 open()
方法具有非标准重载接受 wchar_t *
字符串作为UTF16文件名。
Fortunately, VC++'s implementation of std::ifstream
and std::ofstream
have non-standard overloads of their constructors and open()
methods to accept wchar_t*
strings for UTF16 filenames.
explicit basic_ifstream(
const wchar_t *_Filename,
ios_base::openmode _Mode = ios_base::in,
int _Prot = (int)ios_base::_Openprot
);
void open(
const wchar_t *_Filename,
ios_base::openmode _Mode = ios_base::in,
int _Prot = (int)ios_base::_Openprot
);
void open(
const wchar_t *_Filename,
ios_base::openmode _Mode
);
explicit basic_ofstream(
const wchar_t *_Filename,
ios_base::openmode _Mode = ios_base::out,
int _Prot = (int)ios_base::_Openprot
);
void open(
const wchar_t *_Filename,
ios_base::openmode _Mode = ios_base::out,
int _Prot = (int)ios_base::_Openprot
);
void open(
const wchar_t *_Filename,
ios_base::openmode _Mode
);
您将必须使用 #ifdef
来检测Windows编译(不幸的是,不同的C ++编译器对此有所不同),并在打开文件时将您的UTF8字符串临时转换为UTF16。
You will have to use an #ifdef
to detect Windows compilation (unfortunately, different C++ compilers identify that differently) and temporarily convert your UTF8 string to UTF16 when opening a file.
#ifdef _MSC_VER
std::wstring ToUtf16(std::string str)
{
std::wstring ret;
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
if (len > 0)
{
ret.resize(len);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len);
}
return ret;
}
#endif
int main()
{
std::string utf8path = ...;
std::ifstream iFileStream(
#ifdef _MSC_VER
ToUtf16(utf8path).c_str()
#else
utf8path.c_str()
#endif
, std::ifstream::in | std::ifstream::binary);
...
return 0;
}
请注意,这仅保证在VC ++中有效。其他Windows的C ++编译器不保证提供类似的扩展。
Note that this is only guaranteed to work in VC++. Other C++ compilers for Windows are not guaranteed to provide similar extensions.
这篇关于在C ++ Windows中打开utf8编码的文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!