[英]Getting a boost::filesystem::path as an UTF-8 encoded std::string, on Windows
我们将路径表示为boost::filesystem::path
,但在某些情况下,其他API期望它们为const char *
(例如,使用SQLite打开数据库文件)。
从文档中 , path::value_type
是Windows下的wchar_t
。 据我所知,Windows wchar_t
是2个字节,UTF-16编码。
有一个string()
本机观察者返回一个std::string
,同时说明:
如果string_type是与String不同的类型,则转换由cvt执行。
cvt
初始化为默认构造的codecvt
。 这个默认构造的codecvt的行为是什么?
有这个论坛条目 ,建议使用utf8_codecvt_facet
的实例作为cvt
值,以便可移植地转换为UTF-8。 但似乎这个codecvt实际上是在UTF-8和UCS-4之间转换,而不是UTF-16。
什么是获得path
的std::string
表示的最佳方式(如果可能的话是可移植的),确保在必要时从正确的wchar_t
编码转换?
cvt初始化为默认构造的codecvt。 这个默认构造的codecvt的行为是什么?
它使用默认语言环境转换为特定于语言环境的多字节字符集。 在Windows上,此区域设置通常对应于控制面板中的区域设置。
什么是获得路径的std :: string表示的最佳方式(如果可能的话是可移植的),确保在必要时从正确的wchar_t编码转换?
C ++ 11标准引入了std::codecvt_utf8_utf16
。 虽然它从C++17
被弃用,但根据本文 ,它将“可用”直到合适的替代品被标准化“。
要使用此方面,请调用静态函数:
boost::filesystem::path::imbue(
std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) );
之后,对path::string()
所有调用都将从UTF-16转换为UTF-8。
另一种方法是使用std::wstring_convert< std::codecvt_utf8_utf16<wchar_t> >
来仅在某些情况下进行转换。
完整的示例代码:
#include <boost/filesystem.hpp>
#include <iostream>
#include <codecvt>
void print_hex( std::string const& path );
int main()
{
// Create UTF-16 path (on Windows) that contains the characters "ÄÖÜ".
boost::filesystem::path path( L"\u00c4\u00d6\u00dc" );
// Convert path using the default locale and print result.
// On a system with german default locale, this prints "0xc4 0xd6 0xdc".
// On a system with a different locale, this might fail.
print_hex( path.string() );
// Set locale for conversion from UTF-16 to UTF-8.
boost::filesystem::path::imbue(
std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) );
// Because we changed the locale, path::string() now converts the path to UTF-8.
// This always prints the UTF-8 bytes "0xc3 0x84 0xc3 0x96 0xc3 0x9c".
print_hex( path.string() );
// Another option is to convert only case-by-case, by explicitly using a code converter.
// This always prints the UTF-8 bytes "0xc3 0x84 0xc3 0x96 0xc3 0x9c".
std::wstring_convert< std::codecvt_utf8_utf16<wchar_t> > cvt;
print_hex( cvt.to_bytes( path.wstring() ) );
}
void print_hex( std::string const& path )
{
for( char c : path )
{
std::cout << std::hex << "0x" << static_cast<unsigned>(static_cast<unsigned char>( c )) << ' ';
}
std::cout << '\n';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.