【问题标题】:Conversion from char16_t(utf16) to utf8 doesn't work in visual studio 2015 and 2017从 char16_t(utf16) 到 utf8 的转换在 Visual Studio 2015 和 2017 中不起作用
【发布时间】:2020-08-07 09:36:14
【问题描述】:

我想将数据类型char16_t 转换为utf8,为此我编写了以下代码:

// utf16 String
char16_t *wchs = u"UTF16 string";
// A converter object
wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> conv;
// Convert from utf16 to utf8
string str = conv.to_bytes(wchs);
// print the UTF-16 string after converting to UTF-8
cout << str << endl;

无论是 2015 年还是 2017 年,前面的代码在 Visual Studio 中都不起作用,特别是“char16_t”数据类型,并给我一个错误:
error LNK2001: unresolved external symbol "public: static class std::locale::id std::codecvt&lt;char16_t,char,struct _Mbstatet&gt;::id" (?id@?$codecvt@_SDU_Mbstatet@@@std@@2V0locale@2@A),
但在 GCC 编译器中运行良好。

为什么会发生这种情况以及如何解决这个问题

【问题讨论】:

标签: c++ string utf


【解决方案1】:

您可能不走运,因为这似乎是一个 Visual Studio 错误,因为 VS 开发人员社区页面上至少有 3 个帖子描述了给定的问题

他们都说它已经在哪里了

修复于:visual studio 2019 版本 16.2

没有迹象表明向后移植到 VS 2015 甚至 VS 2017。

【讨论】:

  • 那么,在 vs2015 或 2017 中转换的唯一替代方法是 wchar_t 而不是 char16_t?
  • 可能。它们都用于 Windows 上的 UTF-16,所以一个简单的类型转换就足够了:const char16_t *wchs = u"UTF16 string"; wstring_convert&lt;codecvt_utf8_utf16&lt;wchar_t&gt;, wchar_T&gt; conv; string str = conv.to_bytes(reinterpret_cast&lt;const wchar_t*&gt;(wchs)); 如果您需要为其他平台编译代码,请使用 #ifdef
【解决方案2】:

这是一个简单的函数,你可以如何将 std::u16string 转换为 std::string。它适用于 VS 2017。

std::string utf16_to_utf8( std::u16string&& utf16_string )
{
   std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
   auto p = reinterpret_cast<const int16_t *>( utf16_string.data() );
   return convert.to_bytes( p, p + utf16_string.size() );
}

原因是 wstring_convert&lt;codecvt_utf8_utf16&lt;char16_t&gt;, char16_t&gt; conv; 带有 char16_t 模板参数的声明在 VS 2015 和 VS2017 下无法编译,因为 .cpp 文件中缺少 static locale::id id; 的初始化。 int16_t 类型有效。

在带有 gcc 或 clang 编译器套件的 Linux 下,从 std::u16string 转换会更容易一些。 static locale::id id; 没有问题。

std::string utf16_to_utf8( std::u16string&& utf16_string )
{
   std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
   return convert.to_bytes( utf16_string );
}

【讨论】:

  • 它并没有回答为什么会发生这种情况的问题,您能否详细说明为什么您的解决方案有效而主题启动器无效?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 2016-06-15
相关资源
最近更新 更多