背景:
我正在制作一个散列,它允许您通过向它提供包含其字符的 QString 来查找您在下面看到的描述。
我得到了相关数据的完整列表,看起来像这样:
QHash<QString, QString> lookupCharacterDescription;
...
lookupCharacterDescription.insert("003F","QUESTION MARK");
lookupCharacterDescription.insert("0040","COMMERCIAL AT");
lookupCharacterDescription.insert("0041","LATIN CAPITAL LETTER A");
lookupCharacterDescription.insert("0042","LATIN CAPITAL LETTER B");
...
lookupCharacterDescription.insert("1F648","SEE-NO-EVIL MONKEY");
lookupCharacterDescription.insert("1F649","HEAR-NO-EVIL MONKEY");
lookupCharacterDescription.insert("1F64A","SPEAK-NO-EVIL MONKEY");
lookupCharacterDescription.insert("1F64B","HAPPY PERSON RAISING ONE HAND");
...
lookupCharacterDescription.insert("FFFD","REPLACEMENT CHARACTER");
lookupCharacterDescription.insert("FFFE","<not a character>");
lookupCharacterDescription.insert("FFFF","<not a character>");
lookupCharacterDescription.insert("FFFFE","<not a character>");
lookupCharacterDescription.insert("FFFFF","<not a character>");
现在显然 "1F64B"
需要用一些东西包裹在这里。我曾尝试将 0x1F64B
之类的东西作为 QChar,但老实说,我是在黑暗中摸索。我可以让它使用较低的值,如拉丁字母,但它无法使用 5 个字符的地址。
问题:
- 如何对
1F64B
进行分类? - 这是否被视为 UTF-32?
- 我可以将这个值“1F64B”包装在什么中以生成 QString("🙋")?
- 包装是否也适用于较低的值?
最佳答案
当你使用QString(0x1F64B)
时,它会调用QString::QString(QChar ch)
.由于 QChar
是 16 位类型,它会将值截断为 0xF64B 并且您会得到一个无效字符,因为该代码点当前未分配。我很确定您会在那条线上收到超出范围的警告。如果放大或使用十六进制编辑器,您可以很容易地在字符
中看到值 F64B
。由于无法将 0x1F64B 放入单个 16 位 QChar 中并且必须由代理项对表示,因此您不能以这种方式初始化字符串。
OTOH QString("🙋")
可以工作,因为它是从另一个字符串构造字符串。您必须使用这样的字符串构造字符串,或者通过分配 UTF-8/16 代码单元手动构造字符串。
Is this considered UTF-32?
没有。 UTF-32 是一种 Unicode 编码,它使用 32 位作为代码单元。你只有 QString 而不是一个裸字节数组,所以你不需要关心它的底层编码(实际上是 UTF-16)
What can I wrap this value "1F64B" in to produce the QString("🙋")?
您不应将数值作为字符串处理。而是将其存储为数字类型
QHash<qint32, QString> lookupCharacterDescription;
lookupCharacterDescription.insert(0x1F64B, "HAPPY PERSON RAISING ONE HAND");
然后创建一个包含代码点 0x1F64B 处的字符的字符串,使用
uint cp = 0x1F64B;
QString mystr = QString::fromUcs4(&cp, 1);
Will the wrappings also work for the lower values?
是的,从 UCS4 开始,A.K.A. UTF-32,可以存储任何可能的Unicode字符
或者,您可以从 UTF-16 或 UTF-8 构建字符。 U+1F64B 在 UTF-16 中编码为 D83D DE4B
,或在 UTF-8 中编码为 F0 9F 99 8B
,因此您可以使用以下任何一种
QChar utf16[2] = { 0xD38D, 0xDE4B };
str1 = QString(utf16, 2);
char* utf8[4] = { 0xF0, 0x9F, 0x99, 0x8B };
str2 = QString::fromUtf8(utf8, 4);
如果你想在源代码中以其文字形式包含字符串,那么以下任一方法都可行
str1 = QString::fromWCharArray(L"\xD83D\xDE4B");
str2 = QString::fromUtf8("\xF0\x9F\x99\x8B");
如果您有 C++11 支持,那么只需为 UTF-8、UTF-16 使用前缀 u8
、u
和 U
和UTF-32分别喜欢
u8"🙋"
u"🙋"
U"🙋"
u8"\U0001F64B"
u"\U0001F64B"
u"\uD83D\uDE4B"
U"\U0001F64B"
理解文本和编码的必读文章:There Ain't No Such Thing as Plain Text
关于c++ - 在 Qt 中,如何将 Unicode 代码点 U+1F64B 转换为包含等效字符 "🙋"的 QString?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51903949/