繁体   English   中英

在Windows上获取boost :: filesystem :: path作为UTF-8编码的std :: string

[英]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。

什么是获得pathstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM