2011-01-05 3 views
9

일부 텍스트를보고 문자 패턴에 따라 UTF8 출력을 작성해야합니다. 코드 포인트로 작업하고 UTF8로 변환하면 쉽게 될 거라고 생각했습니다. 유니 코드와 UTF8에 대해 읽었지만 좋은 해결책을 찾을 수 없었습니다. 어떤 도움을 주시면 감사하겠습니다.유니 코드 코드 포인트를 UTF8로 변환하는 C 라이브러리?

답변

33

유니 코드 코드 포인트를 변환 : 난 당신이 단순히 유니 코드 소스를 사용하여 작업을 수행 할 수 있습니다 추측 UTF-8은 라이브러리에 호출을하면 아마 스스로하는 것보다 더 많은 코드 소요 너무 간단하다에 : 그 일을, 또한

if (c<0x80) *b++=c; 
else if (c<0x800) *b++=192+c/64, *b++=128+c%64; 
else if (c-0xd800u<0x800) goto error; 
else if (c<0x10000) *b++=224+c/4096, *b++=128+c/64%64, *b++=128+c%64; 
else if (c<0x110000) *b++=240+c/262144, *b++=128+c/4096%64, *b++=128+c/64%64, *b++=128+c%64; 
else goto error; 

을 스스로 튜닝 w의 유형에 API를 할 수있는 의미 당신이 필요로하는 ork (character-at-time? 또는 긴 문자열?) 입력이 유효한 유니 코드 스칼라 값인 경우 오류 케이스를 제거 할 수 있습니다.

다른 방향은 올바른 것을 얻기가 쉽지 않습니다. 일반적으로 잘못된 문자 시퀀스를 실제 문자의 별칭으로 디코딩하는 일반적인 비트 연산 루프 대신 유한 오토 마톤 방식을 사용하는 것이 좋습니다 (매우 위험하므로 보안 문제가 발생할 수 있음).

편집 : 당신이 도서관에가는 끝내는하더라도, 난 당신이 더 가기 전에 UTF-8 규격을 연구 적어도 심각 먼저 직접 작성 시도하거나해야 하나 생각합니다. 전체적인 요점은 블랙 박스가 아니라 매우 강력한 속성을 갖기 위해 만들어졌으며 UTF-8에 익숙하지 않은 프로그래머가 너무 많아서 UTF-8을 보지 못할 때까지 UTF-8을 블랙 박스로 취급 할 때 많은 잘못된 디자인이 나타날 수 있습니다. 그들은 그들 자신과 많은 일을했습니다.

+6

@ 필립 : 인터페이스 요구 사항에 맞게 라이브러리를 포장하고 더 나은 버그를 해결하려면 더 많은 코드를 작성하고 있습니까? UTF-8을 해독하는 기존 라이브러리 코드를 살펴 보려한다면, 최소한 미묘한 부분에서 대다수가 잘못되었으며 적어도 30 %는 보안 상 심각한 버그가 있음을 알 수 있습니다. (이 추정치는 내가 한동안했던 Google 코드 검색에서 나온 것입니다.) 또한 iconv의 GNU 구현은 한 번에 한 문자 씩 변환하기에는 너무 느린 순서이지만, 의도적 인 부적합)를 입력하십시오. –

+0

내 고급 버전에서 촬영 : http://mercurial.intuxication.org/hg/cstuff/raw-file/tip/utf8_encode.c – Christoph

+2

문자를 거부하면 응용 프로그램에 유용 할 수 있지만 UTF-8 사양 및 일반적으로 올바르지 않습니다. UTF는 코드 단위의 시퀀스 (바이트 또는 큰 단어)와 "유니 코드 스칼라 값"사이의 일대일 맵입니다. 유니 코드 스칼라 값은 정확히 0-0xD7FF 및 0xE000-0x10FFFF의 정수입니다. 이것은 모두 유니 코드 표준에 정의되어 있습니다.이 표준은 사용자 자신의 무언가를 구현하기 전에 읽어야합니다. –

1

어떤 플랫폼입니까? Windows에서 WideCharToMultiByte (CP_UTF8, ...)을 사용할 수 있습니다.

소스 코드 포인트는 UTF-16으로 인코딩해야합니다. 즉, 인코딩 할 수 있어야합니다. 어떤 경우에는 (사로 게이트 쌍), 그것은 사소하지 않습니다.

필자는 주어진 코드 페이지에 텍스트가 있고 유니 코드 (UTF-16)로 변환하려고합니다. 권리? MultiByteToWideChar (codePage, sourceText, ...)/WideCharToMultiByte (CP_UTF8, utf16Text, ...) 왕복이 트릭을 수행합니다.

+0

저는 리눅스에서 일하고 있습니다. – chanux

+0

@chanux : 그러면 다른 답변에서 설명한대로'iconv'를 사용할 수 있습니다. – Philipp

5

아이콘을 사용할 수 있습니다.

#include <iconv.h> 

iconv_t cd; 
char out[7]; 
wchar_t in = CODE_POINT_VALUE; 
size_t inlen = sizeof(in), outlen = sizeof(out); 

cd = iconv_open("utf-8", "wchar_t"); 
iconv(cd, (char **)&in, &inl, &out, &outlen); 
iconv_close(cd); 

는하지만 wchar_t를 유니 코드 코드 포인트를 표현하지 않을 수도 있음을 우려하고 있지만, 임의의 값 .. 편집 :

uint16_t in = UNICODE_POINT_VALUE; 
cd = iconv_open("utf-8", "ucs-2"); 
+2

코드 포인트가 BMP에 없으면 어떻게해야합니까? ucs-2는이를 나타낼 수 없습니다. 하나의 wchar_t는 플랫폼에 따라 충분하지 않을 수 있습니다. 이것이 내가 코드 포인트를 아는 것에 대한 OP의 가정이 잘못되었다고 생각하는 이유입니다. 그렇기 때문에 UTF-32? UTF-16이 분명히 UTF-8이 아니기 때문에 UTF-32를 나타내는 데 사용되는 인코딩 문제가 묻습니다. –

+1

'__STDC_ISO_10646__'이 정의되면 'wchar_t'는 유니 코드 코드 포인트 값입니다. 'wchar_t'가 16 비트라면 이는 BMP 만 지원된다는 것을 의미합니다. UTF-16은 가능하지 않습니다. –

+1

16 비트 'wchar_t'는 UTF-16으로 인코딩 된 문자열에서 사용할 수 있습니다. 즉, BMP 외부의 코드 포인트 값은 인코딩 된 문자열에서 2 개의 'wchar_t'대리 문자를 사용하여 인코딩된다는 것입니다. Windows API는 정확히 이런 종류의 데이터에서 작동하며 정상적으로 작동합니다. –

관련 문제