GrabDuck

Количество байт, которое занимает UTF8 символ в char * строке?

:

Для итерации по словам строки в кодировке UTF8 мне понадобилось разобраться в том, как узнать по-первому байту символа общее количество его байт. Я только начинаю разбираться с UTF8, поэтому не совсем понимаю наверняка механику битовых операций, которая для этого используется (судя по большинству примеров в интернете).


На StackOverflow я нашёл два решения:

1) Способ 1

size_t utf8_char_length(char firstbyte) {
    if ((firstbyte & 0xC0) == 0xC0) {
        if ((firstbyte & 0xF0) == 0xF0) {
            return 4;
        } else if ((firstbyte & 0xE0) == 0xE0) {
            return 3;
        } else {
            return 2;
        }
    } else {
        return 1;
    }
}

2) Второе решение найдено здесь, оно использует другой способ: вместо битовой операции & используется "lookup" по следующему массиву из 256 символов:

static const size_t utf8_skip_data[256] = {
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
};

К сожалению, я сейчас не имею возможности досконально разобраться с UTF8, поэтому просто ищу надёжную функцию, которая будет давать мне правильные результаты для символов в кодировке в UTF8 (точнее для первых байт этих символов). Мне больше нравится второе решение, но я хочу услышать мнение более опытных специалистов:

какую функцию стоит использовать для такой задачи: 1, 2 или, может быть, вы знаете какую-то проверенную свою функцию, которая лучше, чем эти две?

P.S. Кстати, если кто-то может объяснить, откуда взялась lookup-таблица, буду признателен. На SO пишут, что она взята из исходного кода glib's gutf8.c. Так вот интересно, какой принцип лежит в её основе.

Спасибо.