Есть мультибайтовая строка, длина её меряется в мегабайтах, нужно считывать в цикле посимвольно, как считать один символ с мультибайтовой строки?(не используя uchar.h)
Ответ
Берем очередной байт из строки. Предполагая, что это первый байт utf-8 символа
unsigned char b=...; // тут проверяемый байт (обязательно unsigned !!!)
if(b<=0x7F) это однобайтовый символ, можем выдавать его и проверять следующий
else if(b>=0xF8) ... это не unicode символ, или более новый стандарт с более чем 4х байтовыми символами
else if(b>=0xF0) ... это 4х байтовый символ. т.е. берем еще следующие 3 байта
else if(b>=0xE0) ... это 3х байтовый символ. т.е. берем еще следующие 2 байта
else if(b>=0xC0) ... это 2х байтовый символ. т.е. берем еще следующий байт
else ... b - совершенно точно один из серединных байт символа, мы потеряли первый байт
Если символ длиной более 1 байта, то все последующие байты символа должны быть в диапазоне b>=0x80 && b<0xC0
Написал по стандарту RFC3629, надеюсь нигде не ошибся. Можно еще посмотреть код готовых библиотек.
Эх. Обожаю делать велосипеды, вот накидал пример, с разбором кодов символов. Получаемые коды для русских букв сверил с выдаваемых функцией Javascript charCodeAt - совпали. Внимание: собрано на коленке. нет проверок, что строка закончилась в середине символа, при неправильной unicode строке возможен выход за пределы массива ! Трехбайтные и четырехбайтные символы так же не проверены, т.к. не знаю китайского. Так же нет проверки 2го и последующего байта unicode на корректность, тупо сбрасываем старшие 2 бита и используем.
#include
unsigned char *s="Test string. Тестовая строка";
int main()
{
int len=strlen(s);
int i;
int sim_code; // Сюда собираем код очередного символа
for(i=0;i
Универсальный способ получения длины текущего символа:
unsigned char b=s[i]; // Берем первый байт символа
int n; // длина символа
if(b<=0x7F) n=1; ... это однобайтовый символ, работаем с ним как есть
else
for(n=0; b & 0x80; n++) b<<=1;
// после цикла n=полной длине в байтах, включая текущий байт
Комментариев нет:
Отправить комментарий