我们公司正计划让我们的应用程序支持 Unicode,并且我们正在分析我们将遇到的问题。
特别是,例如,我们的应用程序将严重依赖字符串的长度,我们希望将其wchar_t
用作基本字符类。
当处理必须在 UTF-16 中以 2 个 16 位为单位存储的字符时出现问题,即 U+10000 以上的字符。
简单的例子:
我有 UTF-8 字符串“蟂”(Unicode 字符 U+87C2,在 UTF-8 中:E8 9F 82)
所以,我设置了以下代码:
const unsigned char my_utf8_string[] = { 0xe8, 0x9f, 0x82, 0x00 };
// compute size of wchar_t buffer.
int nb_chars = ::MultiByteToWideChar(CP_UTF8, // input is UTF8
0, // no flags
reinterpret_cast<char *>(my_utf8_string), // input string (no worries about signedness)
-1, // input is zero-terminated
NULL, // no output this time
0); // need the necessary buffer size
// allocate
wchar_t *my_utf16_string = new wchar_t[nb_chars];
// convert
nb_chars = ::MultiByteToWideChar(CP_UTF8,
0,
reinterpret_cast<char *>(my_utf8_string),
-1,
my_widechar_string, // output buffer
nb_chars); // allocated size
好的,这行得通,它分配了两次 16 位,我的缓冲区wchar_t
包含 { 0x87c2, 0x0000 }。如果我将它存储在 a 中std::wstring
并计算大小,我得到 1。
现在,让我们以字符 (U+104A2) 作为输入,在 UTF-8 中:F0 90 92 A2。
这一次,它为三个 wchar_t 分配空间并且 std::wstring::size 返回 2即使我认为我只有一个 character。
这是有问题的。让我们假设我们以 UTF-8 格式接收数据。我们可以简单地通过不计算等于的字节来计算 Unicode 字符10xxxxxx
。我们想将该数据导入到数组中wchar_t
以使用它。如果我们只是分配字符数加一,它可能是安全的……直到有人使用 U+FFFF 以上的字符。然后我们的缓冲区将太短,我们的应用程序将崩溃。
那么,对于相同的字符串,以不同的方式编码,计算字符串中字符数的函数会返回不同的值吗?
使用 Unicode 字符串的应用程序是如何设计的以避免这种烦恼?
谢谢您的回复。