【问题标题】:Is there any built-in function that convert wstring or wchar_t* to UTF-8 in Linux?在 Linux 中是否有任何将 wstring 或 wchar_t* 转换为 UTF-8 的内置函数?
【发布时间】:2011-11-20 02:56:57
【问题描述】:

我想将 wstring 转为 UTF-8 编码,但我想使用 Linux 的内置函数。

是否有任何内置函数可以将wstringwchar_t* 在Linux 中通过简单调用 转换为UTF-8?

例子:

wstring str = L"file_name.txt";
wstring mode = "a";
fopen([FUNCTION](str), [FUNCTION](mode)); // Simple invoke.
cout << [FUNCTION](str); // Simple invoke.

【问题讨论】:

  • 你为 wstring 假设什么编码?
  • 如果您使用 std::string,并将其打印到控制台,Linux 终端(至少在 Ubuntu 上)将默认将其解释为 utf-8。
  • @Darcy:好吧,如果当前语言环境是 UTF-8,这是正确的,这是大多数当前 Linux 发行版的默认设置,但不能保证。
  • @DavidHeffernan: linux 上的 std::wstring 总是 UTF-32 不是吗?

标签: c++ c linux utf-8 wstring


【解决方案1】:

如果/当您的编译器支持足够多的 C++11 时,您可以使用 wstring_convert

#include <iostream>
#include <codecvt>
#include <locale>
int main()
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
    std::wstring str = L"file_name.txt";
    std::cout << utf8_conv.to_bytes(str) << '\n';
}

在 Linux 上使用 clang++ 2.9/libc++ 和在 Windows 上使用 Visual Studio 2010 进行测试。

【讨论】:

  • std::wbuffer_convert、std::wstring_convert 和 标头(包含 std::codecvt_mode、std::codecvt_utf8、std::codecvt_utf16 和 std::codecvt_utf8_utf16)在C++17。 (不推荐使用 std::codecvt 类模板。)
  • @A.Danesh 这是一个理想的弃用,就像在 C++98 中弃用的 strstreams,但仍然是 C++20 的强制性部分
【解决方案2】:

C++ 语言标准没有显式编码的概念。它只包含一个“系统编码”的不透明概念,wchar_t 是一个“足够大”的类型。

要将不透明的系统编码转换为显式的外部编码,您必须使用外部库。选择的库是iconv()(从WCHAR_TUTF-8),它是Posix 的一部分,可在许多平台上使用,尽管在Windows 上WideCharToMultibyte 函数保证产生UTF8。

C++11 以std::string s = u8"Hello World: \U0010FFFF"; 的形式添加了新的UTF8 文字。那些已经是 UTF8 格式了,但它们无法与不透明的 wstring 交互,除非通过我描述的方式。

See this question 了解更多背景信息。

【讨论】:

  • C++11的utf-8字符串可以通过wstring_convert与wstrings接口
  • @Cubbi:我仍然不相信这与 UTF8 有任何关系。它看起来只是wcstombs 的包装。 (有一个标题&lt;cuchar&gt; 看起来更有希望。)
  • wstring_convertwcstombs 无关。它是编解码器方面的包装器,例如codecvt_utf8
  • @Kerreck SB:我想我明白你的意思了:除了很少的 函数之外,C++03 的通用窄多字节/宽转换和 C++11 之间没有可移植的连接显式 UTF-8/UTF-16/UTF-16le/UCS2/UTF-32/UCS4 转换。有趣的观察。
【解决方案3】:

如果您真正想要做的是将宽字符转换为当前语言环境,那么 wcstombs 将满足您的需求,这很合理。

如果没有,那么您可能需要看 ICU、boost 或类似的。

【讨论】:

  • wcstombs 没有特定编码的概念。这不是答案。
  • wcstombs 当且仅当当前语言环境为 UTF-8 时才有效。
【解决方案4】:

当然,Linux 上没有内置函数,因为 Linux 的名称仅引用内核,与它没有任何关系。我严重怀疑gcc自带的libc有这样的功能,而且

$ man -k utf

支持这个理论。但是周围有很多好的 UTF-8 库。我个人推荐 iconv 库进行此类转换。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-02-02
  • 2017-12-12
  • 2013-07-28
  • 2011-11-01
  • 2012-02-13
  • 2011-04-06
  • 2011-05-20
相关资源
最近更新 更多