Open utf8 encoded filename in c++ Windows -
consider following code:
#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 file\n"; //do work here. } else { std::cout << "cannot opened file\n"; } return 0; }
if running file, cannot open file entering else
block. using boost::locale::conv::from_utf(utf8path ,"utf_8")
instead of utf8path
doesn't work. code works if consider using wifstream
, using wfilename
parameter, don' want use wifstream
. there way open file name utf8
encoded? using visual studio 2010
.
on windows, must use 8bit ansi (and must match user's locale) or utf16 filenames, there no other option available. can keep using string
, utf8 in main code, have convert utf8 filenames utf16 when opening files. less efficient, need do.
fortunately, vc++'s implementation of std::ifstream
, std::ofstream
have non-standard overloads of constructors , open()
methods accept wchar_t*
strings 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 );
you have use #ifdef
detect windows compilation (unfortunately, different c++ compilers identify differently) , temporarily convert utf8 string utf16 when opening 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 uft8path = ...; std::ifstream ifilestream( #ifdef _msc_ver toutf16(uft8path).c_str() #else uft8path.c_str() #endif , std::ifstream::in | std::ifstream::binary); ... return 0; }
note guaranteed work in vc++. other c++ compilers windows not guaranteed provide similar extensions.
Comments
Post a Comment