在C ++ Windows中打开utf8编码的文件名

考虑下面的代码:

#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

Solutions Collecting From Web of "在C ++ Windows中打开utf8编码的文件名"

在Windows上,您必须使用8位ANSI(且必须匹配用户的区域设置)或UTF16的文件名,因此没有其他选项可用。 您可以继续在主代码中使用string和UTF8,但是在打开文件时,必须将UTF8文件名转换为UTF16。 效率较低,但这是你需要做的。

幸运的是,VC ++对std::ifstreamstd::ofstream具有构造函数的非标准重载和open()方法来接受UTF16文件名的wchar_t*字符串。

 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。

 #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 uft8path = ...; std::ifstream iFileStream( #ifdef _MSC_VER ToUtf16(uft8path).c_str() #else uft8path.c_str() #endif , std::ifstream::in | std::ifstream::binary); ... return 0; } 

请注意,这只能保证在VC ++中工作。 Windows的其他C ++编译器不保证提供类似的扩展名。