C UTF-16解码器未按预期工作

C UTF-16解码器未按预期工作,c,decoding,utf-16,C,Decoding,Utf 16,我的Unicode库中有一部分将UTF-16解码为原始Unicode代码点。然而,它并没有像预期的那样工作 下面是代码的相关部分(省略UTF-8和字符串操作内容): 使用utoc(未显示;我知道它正在工作(见下文))功能将其转换回UTF-8char*进行打印,我可以在终端中看到我得到的是U+0FFFFD,而不是U+10FFFD 在计算器中 在gcalctool中手动执行所有转换会导致相同的错误答案。所以我的语法本身没有错,但算法是错的。虽然算法对我来说似乎是正确的,但它却以错误的答案结束 我做错

我的Unicode库中有一部分将UTF-16解码为原始Unicode代码点。然而,它并没有像预期的那样工作

下面是代码的相关部分(省略UTF-8和字符串操作内容):

使用
utoc
(未显示;我知道它正在工作(见下文))功能将其转换回UTF-8
char*
进行打印,我可以在终端中看到我得到的是
U+0FFFFD
,而不是
U+10FFFD

在计算器中

在gcalctool中手动执行所有转换会导致相同的错误答案。所以我的语法本身没有错,但算法是错的。虽然算法对我来说似乎是正确的,但它却以错误的答案结束


我做错了什么?

解码代理项对时,需要添加0x10000;引用一下,您缺少的步骤是第5步:

1) If W1 < 0xD800 or W1 > 0xDFFF, the character value U is the value of W1. Terminate. 2) Determine if W1 is between 0xD800 and 0xDBFF. If not, the sequence is in error and no valid character can be obtained using W1. Terminate. 3) If there is no W2 (that is, the sequence ends with W1), or if W2 is not between 0xDC00 and 0xDFFF, the sequence is in error. Terminate. 4) Construct a 20-bit unsigned integer U', taking the 10 low-order bits of W1 as its 10 high-order bits and the 10 low-order bits of W2 as its 10 low-order bits. 5) Add 0x10000 to U' to obtain the character value U. Terminate. 1) 如果W1<0xD800或W1>0xDFFF,则字符值U为值 是W1的。终止 2) 确定W1是否在0xD800和0xDBFF之间。若否,次序为何? 存在错误,无法使用W1获取有效字符。 终止 3) 如果没有W2(即序列以W1结尾),或者如果W2 不在0xDC00和0xDFFF之间,序列错误。 终止 4) 构造一个20位无符号整数U',取10低位 W1的10个高阶位和W1的10个低阶位 W2作为其10个低阶位。 5) 将0x10000添加到U'以获取字符值U。终止。 例如,一种修复方法是在第一次阅读后添加一行:

cur = (old.data[i] & 0x3ff) << 10;
cur += 0x10000;

cur=(old.data[i]&0x3ff)您似乎缺少偏移量
0x10000

根据,UTF-16代理项对的构造如下:

UTF-16表示非BMP字符 (U+10000至U+10FFFF)使用两个 代码单元,称为代理项对。 第一个1000016从 代码点给出一个20位的值。 然后将其拆分为两个10位 值,每个值表示为 最有意义的代理 一半被放置在第一个代理中


哇,谢谢!添加了一个简单的缺失步骤,我的UTF-16解码器就可以工作了!没问题,很高兴听到它现在起作用了。谢谢你纠正我的打字错误:) 1) If W1 < 0xD800 or W1 > 0xDFFF, the character value U is the value of W1. Terminate. 2) Determine if W1 is between 0xD800 and 0xDBFF. If not, the sequence is in error and no valid character can be obtained using W1. Terminate. 3) If there is no W2 (that is, the sequence ends with W1), or if W2 is not between 0xDC00 and 0xDFFF, the sequence is in error. Terminate. 4) Construct a 20-bit unsigned integer U', taking the 10 low-order bits of W1 as its 10 high-order bits and the 10 low-order bits of W2 as its 10 low-order bits. 5) Add 0x10000 to U' to obtain the character value U. Terminate.
cur = (old.data[i] & 0x3ff) << 10;
cur += 0x10000;