java - Unicode码指向字节并反转: how do you do that in C++?

标签 java c++ c++11 character-encoding

作为介绍,我从事 Java 工作,过去也从事过相当多的 C 工作。

在 Java 中,一个 String literal 可以包含任何一组字素,只要你可以在你的编辑环境中输入它们;然后,所述编辑环境将以当时使用的任何字符编码保存您的源文件。

在运行时,只要编译器支持编码,字节码代表所有String文字作为一组 char s,其中一个 char代表一个 UTF-16 编码单元。 (因此,BMP 之外的 Unicode 代码点需要两个 char s;您可以使用 char 获得代表 BMP 之外的 Unicode 代码点所必需的 Character.toChars() 数组。

你有一个字符编码类( Charset ),编码一个char序列的过程s 到字节序列 ( CharsetEncoder ) 以及反向 ( CharsetDecoder )。因此,无论您的源/目标使用何种字符编码,无论它是文件、套接字还是其他任何东西,您都可以根据需要进行编码/解码。

现在,让我们假设 C++11。它介绍了std::u32string , std::u16string ;据我所知,这些是 std::basic_string<char32_t> 的“别名”和 std::basic_string<char16_t> ,它们的最终效果是在运行时,您声明的字符串常量(使用 u""U"" )由分别表示 UTF-16 或 UTF-32 代码单元的 16 位或 32 位实体组成。还有u8"" (后者的 basic_string 类型是什么,因为它没有固定长度?)。

其他重点:UTF-16有两个变体,LE和BE; java 确实是 BE,因为在字节码级别,一切都是 BE。是否char{16,32}_t取决于代码中的字节序?

但即使经过几个小时的搜索,我也找不到答案:作为标准,C++11 能否做标准 JDK 做的事情,即将任何字符串常量转换为合适的字节序列,并在给定字符的情况下反向转换编码?我怀疑这变得更加困难,因为在运行时基本上有三种字符串文字表示,甚至没有去 char *这基本上是一个字节数组...


(编辑:添加到相关 javadoc 的链接)

最佳答案

您可以通过使用 codecvt locale facet 进行转换。

用法有点不直观,但这是我所做的:

/** Convert utf8 stream to UCS-4 stream */
u32string decode(string utf8)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>,char32_t> convert;
    return convert.from_bytes(utf8);
}

/** Convert UCS-4 stream to utf8 stream */
string encode(u32string ucs4)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>,char32_t> convert;
    return convert.to_bytes(ucs4);
}

虽然它需要一个像样的编译器,但对我来说只有 clang 可以正常工作,gcc 编译但生成无效结果(较新版本的 gcc 可能没问题)。

关于java - Unicode码指向字节并反转: how do you do that in C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22817699/

相关文章:

c++ - GCC 的 wchar_t 有多大?

c++ - 插入排序的运行时间

Java replaceAll 带换行符

java - 如何替换评论

java - 如何排列 JComboBox 项目

c++ - 迭代 C++ 中的结构

java - 无法在 Java 函数内命中断点

c++ - `constexpr`和 `const`之间的区别

c++ - 唯一键和散列的无序映射

c++ - 这个c++模板函数有什么问题