3

我正在尝试将应用程序从 Java + Swing 转换为 C++ + Qt。在某一时刻,我不得不处理一些 Unicode 中间体。在 Java 中,这相当容易:

private static String[] hiraganaTable = {
    "\u3042", "\u3044", "\u3046", "\u3048", "\u304a", 
    "\u304b", "\u304d", "\u304f", "\u3051", "\u3053", 
    ...
}

...而在 C++ 中我遇到了问题:

QString hiraganaTable[] = {
    "\x30\x42", "\x30\x44", "\x30\x46", "\x30\x48", "\x30\x4a", 
    "\x30\x4b", "\x30\x4d", "\x30\x4f", "\x30\x51", "\x30\x53", 
    ...
};

我不能在 VS2008 中使用 \u 因为我收到了一堆形式的警告:

由通用字符名称“\u3042”表示的字符无法在当前代码页中表示 (1250)

而且不要说我愚蠢,我尝试使用 File->Advanced Save Options 无济于事,代码页似乎根本没有改变。似乎这是一个已知问题:How to create a UTF-8 string literal in Visual C++ 2008

我使用的表格很短,所以在 Vim 和一些入门级的正则表达式魔术的帮助下,我能够将它转换为\x30\x42表示法。不幸的是,QStrings 不会从这样的输入正确初始化。我什么都试过了。fromAscii(), fromUtf8(), fromLocal8Bit(), QString(QByteArray), 作品。然后,尝试将没有 BOM 的 U+3042 写入文件,然后以十六进制模式查看,我发现它实际上是"E3 81 82"。突然,像这样的条目似乎可以与QString::fromAscii()一起使用. 现在我想知道“U+3042”中的“U+”到底代表多少(因为 0xE38182 - 0x3042 = E35140,也许我最好将这个魔术常数添加到我所有可能的 Unicode 字符中?)。我应该如何从这里开始获取正确的 UTF-8 字符串数组?

4

3 回答 3

4

您看到的是该字符的 UTF-8 编码。

>>> u'\u3042'.encode('utf-8').encode('hex')
'e38182'

如果你用 UTF-8 把它们全部写出来,那么你应该没问题。

“U+”只是表示您正在查看 Unicode 代码点,而不是某些特定编码。

编辑:

一个帮助您入门的小脚本,使用 Python(与上述相同的语言):

>>> print ',\n'.join(', '.join('"%s"' % (y.encode('utf-8').encode('string-escape')
      ,) for y in x) for x in [u'あいうえお', u'かきくけこ', u'さしすせそ'])
"\xe3\x81\x82", "\xe3\x81\x84", "\xe3\x81\x86", "\xe3\x81\x88", "\xe3\x81\x8a",
"\xe3\x81\x8b", "\xe3\x81\x8d", "\xe3\x81\x8f", "\xe3\x81\x91", "\xe3\x81\x93",
"\xe3\x81\x95", "\xe3\x81\x97", "\xe3\x81\x99", "\xe3\x81\x9b", "\xe3\x81\x9d"
于 2010-11-23T23:15:44.067 回答
4

问题是 C++ 是基于 C 的,它可以追溯到 ASCII 时代。“默认”C 字符串“abc”是 8 位。您的 Visual C++ 编译器具有 16 位 Unicode (UTF-16) 文字,但语法略有不同:L"abc\u3042". 此类文字的类型wchar_t[N]不是char[N],您可以将它们存储在std::wstring.

Qt 完全理解wchar_t并且可以直接从它们构造 QStrings 而不会出现转换问题。

于 2010-11-24T09:18:39.443 回答
2

“U+ dddd ” 其中每个d是一个十六进制数字,表示一个 Unicode 代码点。

您不能将 16 位值存储在 8 位字符中;这是你遇到的主要问题。

使用宽字符,例如(这些是字符串文字)L"\0x3042"L"\u3042".

然后弄清楚如何让 QString 接受这些。

注意:Visual C++ 会针对\U文字中使用的符号发出 sillywarnings,而 g++ 会针对文字外部使用的符号发出 sillywarnings。

干杯&hth.,

于 2010-11-24T00:21:48.643 回答