在 Linux 中是不是有任何将 wstring 或 wchar_t* 转换为 UTF-8 的内置函数?

Posted

技术标签:

【中文标题】在 Linux 中是不是有任何将 wstring 或 wchar_t* 转换为 UTF-8 的内置函数?【英文标题】: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 不是吗? 【参考方案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 库进行此类转换。

【讨论】:

你的 man 搜索骗了你:Linux glibc 有一个 iconv 实现:gnu.org/s/hello/manual/libc/glibc-iconv-Implementation.html

以上是关于在 Linux 中是不是有任何将 wstring 或 wchar_t* 转换为 UTF-8 的内置函数?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 将 wstring 转换为 Unicode

将 String^ 转换为 wstring C++

如何将 .NET 字符串正确编组为本机代码的 std::wstrings?

在wstring到str转换的CPP问题

将 String^ 转换为 wstring C++

从 DLL 返回 std::wstring 是不是安全?