我需要获得以下十六进制值的UTF8表示,而不是UTF16。我正在使用C++构建器11
setlocale(LC_ALL, ".UTF8");
String tb64 = UTF8String(U"D985");//Hex value of the letter م or M in arabic
std::wstring hex;
for(int i =1; i < tb64.Length()+1; ++i)
hex += tb64[i];
int len = hex.length();
std::wstring newString;
std::wstring byte;
String S;
for(int i=0; i< len; i+=4)
{
byte = hex.substr(i,4);
wchar_t chr =( wchar_t ) ( int) wcstol(byte.c_str(), 0, 16);
newString.push_back(chr);
S = newString.c_str();
}
输出应该是م,它在阿拉伯语中是M,而不是垃圾
发布于 2021-12-07 16:17:11
您将十六进制字符串分配给UTF8String
,然后将其分配给(Unicode)String
,这将将UTF-8转换为UTF-16。然后您将从UTF-16字符创建一个单独的std::wstring
。std::wstring
在Windows上使用UTF-16,在其他平台上使用UTF-32 .
所有这些字符串转换都是不必要的,因为您正在处理ASCII范围中的十六进制字符。所以只需要迭代原始十六进制字符串的字符就可以了,不需要转换.
在任何情况下,您都试图将每个4位数字的十六进制序列直接解码为二进制Unicode码点编号。但在这种情况下,代码点U+D985不是有效的Unicode字符。
"D985"
实际上是Unicode字符م
(编码点U+0645)的十六进制编码的UTF-8字节,所以您需要将每个对2十六进制数字转换成一个字节,并将字节存储为- is,而不是std::wstring
。
RTL有一个StrToInt()
函数,它可以将十六进制编码的UnicodeString
解码为整数,在本例中,您可以将其视为一个字节。
尝试更像这样的东西:
String hex = _D("D985");
int len = hex.Length();
UTF8String utf8;
for(int i = 1; i <= len; i += 2) {
utf8 += static_cast<char>(StrToInt(_D("0x") + hex.Substring(i, 2)));
}
/* alternatively:
UTF8String utf8;
utf8.SetLength(len / 2);
for(int i = 1, j = 1; i <= len; i += 2, ++j) {
utf8[j] = static_cast<char>(StrToInt(_D("0x") + hex.Substring(i, 2)));
}
*/
// use utf8 as needed...
如果需要将解码后的UTF-8转换为UTF-16,只需将UTF8String
分配给UnicodeString
,例如:
UnicodeString utf16 = utf8;
或者,您也可以将解码后的字节存储到TBytes
中,然后使用TEncoding::UTF8
的GetString()
方法,例如:
String hex = _D("D985");
int len = hex.Length();
TBytes utf8;
utf8.Length = len / 2;
for(int i = 1, j = 0; i <= len; i += 2, ++j) {
utf8[j] = static_cast<System::Byte>(StrToInt(_D("0x") + hex.Substring(i, 2)));
}
UnicodeString utf16 = TEncoding::UTF8->GetString(utf8);
// use utf16 as needed...
我只是想到了一个稍微简单一些的解决方案- RTL还有一个HexToBin()
函数,它可以在一次操作中将整个十六进制编码的字符串解码成一个完整的字节数组,例如:
String hex = _D("D985");
UTF8String utf8;
utf8.SetLength(hex.Length() / 2);
HexToBin(hex.c_str(), &utf8[1], utf8.Length());
/* or:
TBytes utf8;
utf8.Length = hex.Length() / 2;
HexToBin(hex.c_str(), &utf8[0], utf8.Length);
*/
// use utf8 as needed...
https://stackoverflow.com/questions/70255986
复制相似问题