std::codecvt_utf8_utf16 不会在大端序中将 UTF-8 转换为 UTF-16

std::codecvt_utf8_utf16 doesn't convert utf-8 to utf-16 in big-endian

本文关键字:UTF-8 UTF-16 转换 utf8 codecvt utf16 std      更新时间:2023-10-16

我使用wstring_convert &将utf-8编码的字符串转换为utf-16编码的字符串。codecvt_utf8_utf16

下面是我测试的示例代码:
#include <iostream>
#include <codecvt>
#include <string>
#include <fstream>
#include <cstdint>
std::u16string UTF8ToWide(const std::string& utf_str)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
    return converter.from_bytes(utf_str);
}
void DisplayBytes(const void* data, size_t len)
{
    const uint8_t* src = static_cast<const uint8_t*>(data);
    for (size_t i = 0; i < len; ++i) {
        printf("%.2x ", src[i]);
    }
}
// the content is:"你好 hello chinese test 中文测试"
std::string utf8_s = "xe4xbdxa0xe5xa5xbd hello chinese test xe4xb8xadxe6x96x87xe6xb5x8bxe8xafx95";
int main()
{
    auto ss = UTF8ToWide(utf8_s);
    DisplayBytes(ss.data(), ss.size() * sizeof(decltype(ss)::value_type));
    return 0;
}

根据参考手册, codecvt_utf8_utf16std::codecvt_mode的默认参数为大端

但是,测试程序显示的字节如下

60 4f 7d 59 2000 68 000 65 000 6c 00 60 c 00 60 f 00 2000 63 00 68 000 694e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e, 4e87 65 4b 6d d5 8b

表示小端序

我分别在Visual Studio 2013和clang上运行测试代码,并最终得到相同的结果。

那么,为什么codecvt_utf8_utf16的大端模式对这些转换没有任何影响?

您引用的同一页说little_endian标志仅用于输入。输出是一个码点序列,而不是字节流。每个代码点都使用平台的正常方式表示——在您的例子中是小端序。

你的程序只是告诉你char16_t是如何在内存中表示的。