C/C++

Как в UTF-8 байт последовательности, где англ 1 байт, а рус 2 байта, парсер поймёт что символ русский, а не 2 англ?

Именно по первому байту символа.
В UTF-8 в первом байте записи символа закодировано, сколько байт занимает весь символ. Если записать значение первого байта в двоичном виде (x - это биты самого символа), то:
0xxxxxxx - 1 байт (7 бит на код символа, код ASCII)
110xxxxx - 2 байта (11 бит на код символа, в том числе, русские буквы)
1110xxxx - 3 байта (16 бит на код символа)
11110xxx - 4 байта (21 бит на код символа)
Все последующие байты символа (если они есть) имеют вид:
10xxxxxx
Рамзиддинхон Ёкубов
Рамзиддинхон Ёкубов
81 844
Лучший ответ
Потому что первый байт русской буквы не соответствует какому-либо символу ASCII.
В UTF-8 один символ может иметь длину до 4 байт.
// Если у байта установлен этот бит, то он - часть многобайтного символа
#define MULTIBYTE_FLAG 0x80
// Если у байта установлен этот бит, то это первый байт
// многобайтного символа
#define HEADERBYTE_FLAG 0x40

Если MULTIBYTE_FLAG не установлен, то байт относится к ASCII и обрабатывается как есть.
Если MULTIBYTE_FLAG установлен, то байт является частью многобайтного символа
Если MULTIBYTE_FLAG установлен И одновременно HEADERBYTE_FLAG установлен, то байт является самым первым байтом многобайтного символа

//-------------------------------------------------------------------
//Функция выделяет из строки str символ в кодировке utf8
//и возвращает его длину.
//Если next != NULL, то по этому указателю записывается
//указатель на начало следующего utf8 символа или NULL
//если строка кончилась и выделять больше нечего
size_tutf8char( char* str, char** next )
{
size_tlen = 0;

if( next )
{
*next = NULL;
}

if( str )
{
//Этот байт часть многобайтного символа?
if( str[len] & MULTIBYTE_FLAG )
{
//Этот байт заголовочный?
if( str[len] & HEADERBYTE_FLAG )
{
len++;
}
//Найдем конец символа
//Символ может кончится либо с окончанием
//строки, либо с началом нового символа
while( str[len] && (str[len] & MULTIBYTE_FLAG) )
{
//Этот байт является заголовочным
//нового мультибайтного символа?
if( str[len] & HEADERBYTE_FLAG )
{
break;
}
len++;
}
}
//Это обычный ASCII байт
else
{
len++;
}

if( next )
{
//Это не конец строки?
if( str[len] )
{
//Вернем указатель на следующий байт
*next = &str[len];
}
//Это конец строки, вернем NULL
else
{
*next = NULL;
}
}
}

returnlen;
}
//-------------------------------------------------------------------

Пример использования:
printf( "Посимвольный разбор строки '%s':\n", ptr );
while( ptr )
{
memset( buf, 0, BUF_SIZE );
//Выделим символ
char_len = utf8char( ptr, &next );
strncpy( buf, ptr, char_len );
printf( "Выделен символ '%s'. Размер байт: %lu\n",
buf, char_len );
ptr = next;
}

Пример разбора
Посимвольный разбор строки 'こんにちは мой Friend':
Выделен символ 'こ'. Размер байт: 3
Выделен символ 'ん'. Размер байт: 3
Выделен символ 'に'. Размер байт: 3
Выделен символ 'ち'. Размер байт: 3
Выделен символ 'は'. Размер байт: 3
Выделен символ ' '. Размер байт: 1
Выделен символ 'м'. Размер байт: 2
Выделен символ 'о'. Размер байт: 2
Выделен символ 'й'. Размер байт: 2
Выделен символ ' '. Размер байт: 1
Выделен символ 'F'. Размер байт: 1
Выделен символ 'r'. Размер байт: 1
Выделен символ 'i'. Размер байт: 1
Выделен символ 'e'. Размер байт: 1
Выделен символ 'n'. Размер байт: 1
Выделен символ 'd'. Размер байт: 1
JT
Johann Tagne
9 624