簡體   English   中英

如何“解碼” UTF-8字符?

[英]How do I “decode” a UTF-8 character?

假設我要編寫一個比較兩個Unicode字符的函數。 我應該怎么做? 我讀了一些文章(像這樣 ),但還是沒有。 讓我們以作為輸入。 它的范圍是0x08000xFFFF因此它將使用3個字節對其進行編碼。 如何解碼? wchar_t獲取3個字節並存儲到3個char的按位運算? 用C語言編寫的示例代碼可能很棒。

這是我的C代碼“解碼”,但顯然顯示錯誤的值來解碼unicode ...

#include <stdio.h>
#include <wchar.h>

void printbin(unsigned n);
int length(wchar_t c);
void print(struct Bytes *b);

// support for UTF8 which encodes up to 4 bytes only
struct Bytes
{
    char v1;
    char v2;
    char v3;
    char v4;
};

int main(void)
{
    struct Bytes bytes = { 0 };
    wchar_t c = '€';
    int len = length(c);

    //c = 11100010 10000010 10101100
    bytes.v1 = (c >> 24) << 4; // get first byte and remove leading "1110"
    bytes.v2 = (c >> 16) << 5; // skip over first byte and get 000010 from 10000010
    bytes.v3 = (c >> 8)  << 5; // skip over first two bytes and 10101100 from 10000010
    print(&bytes);

    return 0;
}

void print(struct Bytes *b)
{
    int v1 = (int) (b->v1);
    int v2 = (int)(b->v2);
    int v3 = (int)(b->v3);
    int v4 = (int)(b->v4);

    printf("v1 = %d\n", v1);
    printf("v2 = %d\n", v2);
    printf("v3 = %d\n", v3);
    printf("v4 = %d\n", v4);
}

int length(wchar_t c)
{
    if (c >= 0 && c < 0x007F)
        return 1;
    if (c >= 0x0080 && c <= 0x07FF)
        return 2;
    if (c >= 0x0800 && c <= 0xFFFF)
        return 3;
    if (c >= 0x10000 && c <= 0x1FFFFF)
        return 4;
    if (c >= 0x200000 && c <= 0x3FFFFFF)
        return 5;
    if (c >= 0x4000000 && c <= 0x7FFFFFFF)
        return 6;

    return -1;
}

void printbin(unsigned n)
{
    if (!n)
        return;

    printbin(n >> 1);
    printf("%c", (n & 1) ? '1' : '0');
}

比較UTF-8編碼的字符並不容易。 最好不要嘗試。 或者:

  1. 將它們都轉換為寬格式(32位整數),然后進行算術比較。 請參閱wstring_convert或您最喜歡的供應商特定函數; 要么

  2. 將它們轉換為1個字符串,並使用一個比較UTF-8編碼字符串的函數。 在C ++中沒有標准的方法來執行此操作,但是它是其他語言(例如Ruby,PHP等)中的首選方法。


為了清楚起見,很難做到的是獲取編碼為UTF_8的原始位/字節/字符並進行比較。 這是因為您的比較必須考慮編碼才能知道是比較8位,16位還是更多位。 如果您可以通過某種方式將原始數據位轉換為以零結尾的字符串,則使用常規字符串函數比較起來非常容易。 該字符串的長度可能超過一個字節/八位字節,但是它將代表一個字符/代碼點。


Windows有點特殊情況。 寬字符為short int(16位)。 從歷史上講,這意味着UCS-2,但已將其重新定義為UTF-16。 這意味着可以直接比較基本多語言平面(BMP)中的所有有效字符,因為它們將占據單個short int,而其他字符則不能。 我不知道有任何簡單的方法可以在Windows上的BMP之外處理32位寬的字符(表示為簡單的int)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM