使用Boost将UTF-16BE转换为UTF-8.Locale会产生垃圾
UTF-16BE to UTF-8 using Boost.Locale yields garbage
我正在使用一个返回UTF-16BE字符串的API。我需要将它们转换为UTF-8,以便在UI中显示(而UI又接受char*缓冲区)。为此,我决定使用boost::locale::conv::utf_to_utf()
并编写一个转换例程:
// defined by the API
typedef uint16_t t_wchar_t;
typedef std::basic_string<t_wchar_t> t_wstring;
char* ToUtf8(const t_wstring &utf16)
{
// print out the input buffer, using printfs instead of cout because I have to
printf("t_wchar_t = %zu, wchar_t = %zu, char = %zun",
sizeof(t_wchar_t), sizeof(wchar_t), sizeof(char));
const t_wchar_t *inBuf = utf16.c_str();
const size_t inSize = utf16.size();
// buf2str is my debugging function for printing buffers as raw bytes
printf("UTF16 size: %zu, buf: %sn", inSize,
buf2str(inBuf, inSize).c_str());
// make a copy of the input buffer, prepend a BE BOM
// (didn't work without it, does not work with it either)
t_wchar_t *workBuf = new t_wchar_t[inSize + 1];
workBuf[0] = 0xfeff;
std::memcpy(workBuf + 1, inBuf, inSize * sizeof(t_wchar_t));
printf("Workbuf: %sn", buf2str(workBuf, inSize + 1).c_str());
// perform conversion, print out the result buffer
const string utf8Str = boost::locale::conv::utf_to_utf<char>(workBuf,
workBuf + inSize + 1);
const size_t utf8Size = utf8Str.size();
printf("UTF8 size: %zu, buf: %sn", utf8Size,
buf2str(utf8Str.c_str(), utf8Size).c_str());
// allocate a char buffer, copy the result there and return the pointer
char *ret = new char[utf8Size + 1];
std::memcpy(ret, utf8Str.c_str(), (utf8Size + 1)*sizeof(char));
printf("Return buf[%zu]: <%s>n",
buf2str(ret, utf8Size + 1).c_str());
delete [] workBuf;
return ret;
}
然而,当在API字符串上运行时,它会返回垃圾以及一些测试数据:
int main()
{
// simulate the input, make an example UTF-16BE stream from raw bytes
const unsigned char test[] ={ ' ', 'H', ' ', 'e', ' ', 'l', ' ', 'l', ' ', 'o',
' ', ',', ' ', ' ', ' ', 'w', ' ', 'o', ' ', 'r', ' ', 'l',
' ', 'd', ' ', '!' };
// create a t_wstring from the 16bit code sequences directly
const t_wstring testStr(reinterpret_cast<const t_wchar_t*>(test), 13);
printf("test data: %sn", buf2str(testStr.c_str(), testStr.size()).c_str());
char* utf8 = ToUtf8(testStr);
delete [] utf8;
return 0;
}
以下是程序中"Hello,world!"字符串的一些输出。正如您所看到的,转换后的UTF8缓冲区包含垃圾。
测试数据:[13/26]''(0)'H'(72)''(0"(0)"(32)"(33)
t_wchar_t=2,wchar_t=4,char=1
UTF16大小:13,buf:[13/26]''(0)'H'(72)''(0"(0)","(44)"(0)""(0)"!"(33)
工作区:[13/26]''(0)'H'(72)''(0"(0)"(32)"(33)
UTF8大小:42,buf:[42/42]''(228)''(160)''(128)''(230)''(148)''''(176)''(128)''(230)''(188)''(128''(226)''(176''(128)''(230)''(188)''(128(226)(132)(128)(226)"(188)"(179)
我做错了什么?谢谢
编辑:感谢@TheUndadFish的评论,我在转换之前在我的工作缓冲区上添加了endianness转换,现在它如预期一样工作:
for (size_t i = 0; i < inSize; ++i)
{
workBuf[i] = be16toh(workBuf[i]);
}
在您的案例中,utf_to_utf
似乎正在处理输入,就好像它是小端UTF16一样。
取前4个字节:
你的意思是00 72 00 101编码为U+0048 U+0064。
当在编码U+4800 U+6400的相反序下进行解释时。
当它被转换为UTF-8时,结果是字节e4 a0 80 e6 94 80。
将它们表示为十进制得到228 160 128 230 148 128,这是"垃圾"的第一个值。
- HEX值到wchar_t字符(UTF-8)的转换
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 转换特殊字符(UTF-8)
- 如何在CPP的给定目录中列出UTF编码的文件名?
- 如何使用 C++将 ISO-2022-KR 编码转换为 UTF-8 编码?
- 在C++中使用 UTF-8 字符串和字符
- 如何将 UTF-8 文本从文件转换为某个可以迭代的容器,并检查每个符号是否为C++字母数字?
- 将C++ std::string 转换为 UTF-16-LE 编码的字符串
- 在基于英语的系统上将 UTF-8 路径转换为宽字符会引发异常
- C++ 将 UTF-8 转换为字符串
- 从/到 UTF-8/UTF-16 的转换需要(例如:utf8 -> 代码点,然后代码点到 utf16)或(例如:utf8 -> utf16)?
- 通过分隔符分隔包含 UTF-16 BE 文本的uint8_t数组
- 一种从内存中删除 UTF 字节的方法?
- 与 boost::locale 关于"ß"大写的例外行为混淆
- "C.UTF-8" C++ Windows 上的语言环境?
- 使用 std::locale 格式化法语数字时无效的 UTF-8 数据
- std::locale 向"en_US.UTF-8"区域设置抛出runtime_error异常
- 为什么当我将 std::locale 设置为 "zh_CN.UTF-8" 时 std::istringstream 失败?
- 为什么我不能在窗口上使用 boost::locale::conv::between 将 UTF-16 文本转换为其他编码
- 使用Boost将UTF-16BE转换为UTF-8.Locale会产生垃圾