如何在c ++中从二进制文件中获取utf-8字符?

时间:2012-05-25 17:01:06

标签: c++ utf-8 binary

例如,我有:11100011 10000010 10100010。它是:的二进制文件; 它在UTF-8中的数字是:12450

如何从二进制中获取此数字?

2 个答案:

答案 0 :(得分:1)

您显示的字节序列是字符的UTF-8编码版本。

您需要解码 UTF-8才能进入Unicode代码点。

对于这个确切的字节序列,以下位构成代码点:

11100011 10000010 10100010
    ****   ******   ******

因此,连接带星号的位,我们得到数字0011000010100010,等于0x30a2或十进制12450。

有关如何解释编码的详细信息,请参阅Wikipedia description

简而言之:如果在第一个字节中设置了第7位,那么同样设置的相邻位数(称为 m )(2)给出了此后的字节数代码点。从每个字节中提取的位数对于第一个字节是(8 - 1 - 1 - m ),对于每个后续字节是6位。所以我们得到(8 - 1 - 1 - 2)= 4 + 2 * 6 = 16位。

正如评论中指出的那样,有很多库可供您使用,因此您可能不需要自己实现它。

答案 1 :(得分:1)

wikipedia page工作,我想出了这个:

unsigned utf8_to_codepoint(const char* ptr) {
    if( *ptr < 0x80) return *ptr;
    if( *ptr < 0xC0) throw unicode_error("invalid utf8 lead byte");
    unsigned result=0;
    int shift=0;
    if( *ptr < 0xE0) {result=*ptr&0x1F; shift=1;}
    if( *ptr < 0xF0) {result=*ptr&0x0F; shift=2;}
    if( *ptr < 0xF8) {result=*ptr&0x07; shift=3;}
    for(; shift>0; --shift) {
        ++ptr;
        if (*ptr<0x7F || *ptr>=0xC0) 
            throw unicode_error("invalid utf8 continuation byte");
        result <<= 6;
        result |= *ptr&0x6F;
    }
    return result;
}

请注意,这是一个非常糟糕的实现(我非常怀疑它甚至编译),并解析了很多可能不应该的无效值。我这样做只是为了表明它比你想象的要难得多,并且你应该使用一个好的unicode库。