아래의 솔루션은 유니 코드 공간의 하위 16 비트가 충분하다고 가정합니다. 비트 맵 테이블이 위치 0x00 ~ 0x5E에서 U + 00A ~ U + 0000, 위치 0x5F ~ 0xBE에 U + 00A0에서 U + 00FF, 0xBF에서 0xFF에 U + 1200 ~ U + 1241이라면 다음과 같은 작업을 수행 할 수 있습니다. 아래의 코드 (테스트되지 않았고 심지어 컴파일 테스트되지 않음).
bitmapmap에는 일련의 값 쌍이 들어 있습니다. 첫 번째 쌍의 첫 번째 값은 인덱스 0의 비트 맵이 나타내는 유니 코드 코드 포인트입니다. 비트 맵 테이블에는 일련의 직접 인접한 유니 코드 코드 포인트가 포함된다고 가정합니다. 두 번째 값은이 시리즈의 지속 시간을 나타냅니다.
while 루프의 첫 번째 부분은 UTF-8 입력을 반복하고 ucs2char에서 유니 코드 코드 포인트를 작성합니다. 완전한 문자가 발견되면, 두 번째 부분은 bitmapmap에 언급 된 범위 중 하나에서 해당 문자를 검색합니다. 적절한 비트 맵 인덱스를 찾으면이를 인덱스에 추가합니다. 비트 맵이없는 문자는 자동으로 삭제됩니다.
이 함수는 찾은 비트 맵 인덱스의 수를 반환합니다.
이 작업을 수행하는 방법은 유닉스 -> 비트 맵 테이블의 관점에서 합리적으로 빠르고 합리적으로 유연해야합니다.
// Code below assumes C99, but is about three cut-and-pastes from C89
// Assuming an unsigned short is 16-bit
unsigned short bitmapmap[]={0x0020, 0x005E,
0x00A0, 0x0060,
0x1200, 0x0041,
0x0000};
int utf8_to_bitmap_indexes(unsigned char *utf8, unsigned short *indexes)
{
int bitmapsfound=0;
int utf8numchars;
unsigned char c;
unsigned short ucs2char;
while (*utf8)
{
c=*utf8;
if (c>=0xc0)
{
utf8numchars=0;
while (c&0x80)
{
utf8numchars++;
c<<=1;
}
c>>=utf8numchars;
ucs2char=0;
}
else if (utf8numchars && c<0x80)
{
// This is invalid UTF-8. Do our best.
utf8numchars=0;
}
if (utf8numchars)
{
c&=0x3f;
ucs2char<<=6;
ucs2char+=c;
utf8numchars--;
if (utf8numchars)
continue; // Our work here is done - no char yet
}
else
ucs2char=c;
// At this point, we have a complete UCS-2 char in ucs2char
unsigned short bmpsearch=0;
unsigned short bmpix=0;
while (bitmapmap[bmpsearch])
{
if (ucs2char>=bitmapmap[bmpsearch] && ucs2char<=bitmapmap[bmpsearch]+bitmapmap[bmpsearch+1])
{
*indexes++ = bmpix+(ucs2char-bitmapmap[bmpsearch]);
bitmapsfound++;
break;
}
bmpix+=bitmapmap[bmpsearch+1];
bmpsearch+=2;
}
}
return bitmapsfound;
}
EDIT : 하위 16 비트 이상을 필요로한다고 언급했습니다. s/unsigned short/unsigned int /; s/ucs2char/codepoint /; 위의 코드에서 전체 유니 코드 공간을 수행 할 수 있습니다.
훌륭한 답변, 도움 주셔서 감사합니다. –