0

我混合了 ASCII 和 UTF-16 字符串,主要问题是,我需要以某种方式将其拆分为字符串中的每个字符。例如假设我们在 Windows 下并且(在大多数情况下)默认编码是 UTF-16:

const wchar_t msg[] = L"AД诶B";

我总共定义了 4 个字符。

A = 2 bytes.
Д = 2 bytes.
诶 = 4 bytes.
B = 2 bytes.

我需要从字符串中取出第 4 个字符(ASCII B),但是如果我执行 msg[4] 它将拆分中文关键字并返回错误的结果。如果没有任何额外的库,我该如何解决这个问题?

4

1 回答 1

3

正如您已经发现的那样,UTF-16 实际上是一种可变宽度编码。因此,您必须扫描字符串以执行准确的字符索引。

幸运的是,很容易判断一个字符是否是多词序列的一部分:UTF-16 中唯一的多词序列(如当前定义)是代理对:[D800-DBFF] 范围内的一个词后跟一个[DC00-DFFF] 范围内的字。因此,当您遇到这样的序列时,请将其视为单个字符。

这可能会满足您的需求:

UChar32 utf16_char_at_index(const wchar_t *s, off_t index) {
    while(1) {
        if(s[0] >= 0xd800 && s[0] <= 0xdbff) {
            /* First half of surrogate pair; check next half */
            if(s[1] >= 0xdc00 && s[1] <= 0xdfff) {
                /* surrogate pair: skip or return */
                if(index == 0) {
                    return ((s[0] - 0xd800) << 10) | (s[1] - 0xdc00);
                }
                s += 2;
                index--;
                continue;
            }
            /* Otherwise, decoding error...may want to flag error here */
        }
        if(index == 0) {
            return s[0];
        }
        s++;
        index--;
    }
}
于 2013-07-31T02:23:34.617 回答