c++ - 在 Qt 中,如何将 Unicode 代码点 U+1F64B 转换为包含等效字符 "🙋"的 QString?

标签 c++ qt unicode qstring qchar

背景:

我正在制作一个散列,它允许您通过向它提供包含其字符的 QString 来查找您在下面看到的描述。

Character map example

我得到了相关数据的完整列表,看起来像这样:

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 使用前缀 u8uU和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/

相关文章:

python - 在python 3中将utf-8编码的字符串转换为纯文本

java - 为什么这不起作用字符串 a = "\u"+ "30A0";?

c++ - 在 VS2005 中为我的 C++ 应用程序设置管理员权限

c++ - 学习 C++ 标准库——一个好主意?

java - java或c++中的动态分配

c++ - 将 unsigned char* 转换为 std::string

c++ - 表单自动保存问题

C++ 文本文件不会保存在 Unicode 中,它一直保存在 ANSI 中

qt - 无法访问 TabView/Tab 内的项目

c++ - 在工作线程中创建的 QObject 的线程亲和性会发生什么,然后终止?