【问题标题】:How to convert a utf16 ushort array to a utf8 std::string?如何将 utf16 ushort 数组转换为 utf8 std::string?
【发布时间】:2012-12-03 04:17:48
【问题描述】:

目前我正在编写一个插件,它只是一个现有库的包装器。 插件的主机传递给我一个 utf-16 格式的字符串,定义如下

typedef unsigned short PA_Unichar;

并且被包装的库只接受一个 const char* 或一个 std::string utf-8 格式的字符串 我试着写一个像

这样的转换函数
std::string toUtf8(const PA_Unichar* data)
{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
return std::string(convert.to_bytes(static_cast<const char16_t*>(data));
}

但显然这不起作用,给我一个编译错误“不允许从'const指针'(又名'const unsigned short*')到'const char16_t *'的static_cast”

那么最优雅/正确的方法是什么?

提前谢谢你。

【问题讨论】:

  • std::is_same&lt;unsigned short, char16_t&gt;::value 在您的平台上的价值是多少?另外,哪个编译器?
  • std::is_same&lt;unsigned short, char16_t &gt;::value 的值为 0 (false),我在 Mac 上使用 Apple LLVM 编译器 4.1 进行编译,但我也使用 Visual Studio 2012 进行交叉编译
  • 根据open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2018.htmlchar16_tuint16_least_t,而不是uint16_t。在您的平台上,uint16_least_t 看起来 别名为 unsigned short,因此是 sizeof(char16_t) != sizeof(unsigned short)。当底层sizeofs 不匹配时,static_cast 将在指针类型上失败。
  • char16_t 根据定义是 16 位的。如果 unsigned short 用于 UTF-16,那么它也必须是 16 位的。我要么将PA_Unicode 更改为uint16_t,要么使用reinterpret_cast 而不是static_cast
  • 在我看到答案之前,我使用了后一种方式,当然我可以替换 typedef,但由于我不维护 API,所以我不能冒每次更新时破坏代码的风险。我希望编写接口的人只使用标准类型

标签: c++ utf-8 c++11 utf-16


【解决方案1】:

您可以使用basic_string(Iterator, Iterator) 构造函数将PA_unichar 字符串转换为char16_t 字符串,然后按照您的尝试使用std::codecvt_utf8_utf16 方面:

std::string conv(const PA_unichar* str, size_t len)
{
  std::u16string s(str, str+len);
  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
  return convert.to_bytes(s);
}

认为没错。不幸的是,我无法对此进行测试,因为我的实现还不支持它。我有一个 wstring_convert 的实现,我计划将它包含在 GCC 4.9 中,但我没有一个 codecvt_utf8_utf16 的实现来测试它。

【讨论】:

  • 非常感谢,它似乎运行良好,这也使我免于一些糟糕的类型转换:)
  • 太好了,我很高兴我脑子里的编译器正确地进行了类型检查!出于兴趣,您正在使用哪个编译器支持这些类?
  • 我在基于 Mac 的系统上使用 LLVM 4.1 编译器(在设置标志 -std=c++11 之后)和 Windows 系统上的 Visual Studio 2012 进行编译
  • 感谢您的加入 - 我想我最好完成我的 GCC 实施,然后如果竞争对手有它!我没有看到对这些课程的任何需求,我认为大多数人甚至都不知道它们的存在
  • Drat,codecvt_utf8_utf16 不在 gcc 4.8 中。希望 Jonathan Wakely 能达到 gcc 4.9 的标准。对我来说太晚了。
猜你喜欢
  • 2020-03-03
  • 2021-08-21
  • 2019-08-27
  • 2012-11-04
  • 2012-02-13
  • 1970-01-01
  • 2014-02-24
  • 2011-09-11
  • 2013-08-26
相关资源
最近更新 更多