[완료] UTF-16LE 문자열의 길이를 알아내는 방법은?
글쓴이: poplinux / 작성시간: 목, 2007/03/15 - 12:01오후
EUC-KR 을 UTF-16 으로 변환하는 프로그램을 iconv 를 사용해서 짜고 있습니다.
물론 알고 계시겠지만, iconv() 함수의 리턴값이 전체 문자열의 길이를 리턴해 준다는 보장이 없습니다. 그래서 그 부분을 사용하기는 어렵습니다.
다음과 같은 EUC-KR 문자열을 UTF-16으로 변환하면
string = "abcd 나는 당신을 사랑합니다. cfg 123456"
strlen() 함수를 사용해서 길이를 알아보게 될 경우 1 로 나옵니다. 아마도 UTF-16 으로 인코딩 된 문자열 중간에 strlen() 에서 NULL 문자로 인식하는 부분이 있나 봅니다.
혹시나 해서
EUC-KR 을 UTF-8로 바꾸었을 경우엔 정상적인 길이가 나옵니다.
문자열의 길이가 필요한 이유는 문자열 앞에 헤더를 붙이는데 그 헤더에 문자열의 길이가 들어가기 때문입니다.
어떻게 해야 변환된 문자열의 총길이를 알아낼수 있을까요?
Forums:
size_t iconv(iconv_t cd,
아시다시피 outbytesleft 는 output buffer 의 남은 공간입니다.
변환 후 남은 공간의 크기를 알 수 있다면, 사용된 공간의 크기를 계산할 수 있지 않겠습니까 ?
"문자열의 길이" 라는 게 정말로 의미심장하긴 합니다만.
씨에서 문자열은 NULL
씨에서 문자열은 NULL 문자열입니다.
예를 들어 "a" 라는 문자열은 65 00 요렇게 되죠.
그래서 길이를 처리할 때 처음부터 00 까지 몇 바이트인가를 셉니다.
그런데 utf-16 인코딩은 NULL 문자열과 호환이 안됩니다.
왜냐하면 모든 문자를 16비트로 표현하는데, ascii 부분을 포함한 0~255 사이에 있는 문자를 표현할때 전부 00 이 앞에 붙어 버립니다.
utf-16le 이면 little endian 이므로..
string = "abcd 어쩌구~"
는
65 00 66 00 ....
이렇게 나가므로, strlen(string) 하면 1이 리턴 되는 것입니다. 널 문자까지 1바이트 밖에 없으니까요.
utf-8의 경우 문자열을 처음부터 씨 문자열과 호환을 염두에 두고 만든 것이므로 NULL 문자열과 호환이 됩니다. 널 문자를 제외한 어떤 문자도 00 이라는 8비트 시퀀스를 포함하지 않습니다. 그래서 제대로 된 값이 나오는 것입니다.
해결책은 유니코드 문자열을 쓰시고 wcslen 함수를 쓰는 것입니다.
char 대신에 wchar_t, "" 대신에 L"" 을 쓰시고 wcslen() 함수를 이용해 보세요. 여기서 언급한 것은 대충 언급한 것이니, 자세한 것은 unicode FAQ 등을 보시고, 임시 방편으로 때우시려면 그냥 (sizeof(string) - 2) / 2 하시면 문자열 길이가 나올 것입니다. utf-16 에서 널문자 크기는 2바이트 이니까요. 이 경우는 각 문자가 BMP 영역 내에 있는 경우에만 해당 됩니다. 이상한 옛날 한문 같이 BMP 이후에 있는 문자는 아마 4바이트로 인코딩 되니까요.
UTF16이면 1문자 =
UTF16이면 1문자 = 2byte입니다.
직접 만드시겠다면 입력 문자열 포인터를 unsigned short *포인터로 바꾼뒤에 0이 나올때까지의 수를 세면 됩니다.
그리고 바이트단위 길이를 잰다면 0이 나오기 전까지의 unsigned short의 갯수 *2하면 되고요.
문자수만 센다면 중간에 대행코드 나오면 unsigned short 두개가 한문자를 이루니 그걸 처리해야합니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
UTF16의 문자가 항상 2바이트 인 것은 아닙니다.
UTF16의 문자가 항상 2바이트 인 것은 아닙니다.
http://en.wikipedia.org/wiki/UTF-16
Examples 부분만 보셔도 언제나 2바이트가 아니란 것을 아실 수 있을 겁니다.
어떤 부분에서 2바이트가 아닌 4바이트가 되는지는 위 링크의 Encoding of characters outside the BMP 부분을 보시면 됩니다~
감사합니다.
감사합니다.
========================
조직 : E.L.D(Embedded Linux Developer/Designer)
블로그 : poplinux@tistory.com
카페 : cafe.naver.com/poplinux
임베디드 리눅스 관련 프리렌서 지향
댓글 달기