컨텐츠 바로가기

유니코드와 멀티바이트 코드

http://HardCoding.egloos.com/557949

※character ser이란?

예전에 미국에서 영어를 표한하기 위해 아스키 코드라는 character set을 만들었다.


character set이란 숫자와 문자의 관계? 또는 문자표 라고 생각하면 된다.


예를 들어 아스키 코드같은 경우에는 char형으로 저장을 하는데

 
char가 문자형이라고 해봐야 일단은 1바이트의 메모리공간으로 메모리에 존재하는 것은 그저 2진수 숫자 뿐이다.


이러한 char로 문자를 표현할 수 있는 이유는 숫자와 문자사이의 표를 만들어 표준으로 정하고 사용하기 때문이다.


예를 들면 숫자 65는 A이다. 숫자 97은 a이다. 이런 형식이다.


참고로, 대문자랑 소문자랑 다른 수 이다. 따라서 A == a 는 거짓이다.




※아스키 코드

char은 8비트로 2의8승-1 로 총 255가지의 숫자를 가지고 있다.


그러므로 아스키 코드는 255가지의 문자를 표현할 수 있을거라 생각할수도 있지만 1비트는 따로 사용하는 용도가 정해져 있다.


그러므로 총 7비트만큼 문자를 표현하는데 사용하고 있다.


아스키 코드표는 외울 필요가 없고, 인터넷에 아스키코드를 검색하면 표를 쉽게 찾을 수 있으니 궁금할때마다 참고 하면된다.




※멀티 바이트 코드

아스키 코드는 1바이트로 문자를 표현한다.(1비트는 어떠한 이유로 사용하지않음)


1바이트는 7비트로 128가지의 문자를 표현하는데 세상의 문자가 128가지는 아니다.


한글도 있고 일본어도 있다. 이러하다보니 1바이트로 처리하기에는 표현할 수 있는 범위가 너무 좁았다.


그 문제점을 해결하기위한 방법중 하나가 멀티 바이트 코드다.


멀티바이트 코드는 영어같은 아스키 코드에 포함되는 문자는 1바이트로 표현하고, 포함되지 않는 문자는 2바이트로 포현한다.


따라서 'abc안녕'와 같은 문자열은 'abc'는 3바이트, '안녕'은 4바이트에 NULL문자 1바이트로 총 8바이트가 할당된다.


얼핏보면 굉장히 효율적인 구조라 할수도 있다.


물론 멀티바이트가 나쁜건 아니지만 몇가지 문제점을 가지고 있다.


영어는 1바이트로 표현하고 한글은 2바이트로 표현하기 때문에 문자열을 다루는 프로그래밍을 할때 코딩이 어렵다.


또한 strlen같은 함수를 사용했을시 한글을 2자리로 인식해서 버그의 소지가있다.


물론 이것을 숙지하고 프로그래밍을 한다면 메모리를 효과적으로 사용할 수는 있겠으나 그것은 프로그래머를 피곤하게 하고 1바이트 문자인지 2바이트 문자인지 체크하는 코드 때문에 성능의 저하가 생길것이다.

따라서 최근 사용되는 character set은 유니코드이다.




※유니코드

유니코드는 멀티바이트와 달리 한글이든 영어든 항상 2바이트의 메모리를 할당한다.


아스키코드의 한계점과 멀티바이트의 문제점을 해결할 수 있는 형태이다.


하지만 이러한 유니코드의 경우에도 문제점이있다.


바로 strlen으로 길이를 조사했을때 'avb하나'를 총 10글자로 인식해버린다. strlen은 아스키 코드 문자열을 위한 함수이기 때문이다.


흔히들 사용해온 printf, scanf등은 전부 아스키코드를 위한 함수였던 것이다.


유니코드 문자열을 위한 입출력 함수는 따로 존재한다. 예를 들면 printf의 유니코드 버전은 wprintf이다.


strlen의 유니코드 버전은 wcslen이고 strcat, strcpy, strcmp, strncpy의 유니코드 버전은 wcscat, wcscpy, wcscmp, wcsncpy이다.


유니코드는 char 형이 아닌 wchar_t형을 사용한다. wchar_t는 unsigned short를 typedef으로 재정의 한 것인데 2바이트다.


또한 유니코드는 일반적인 문자열을 대입해선 안된다.


예를들어 "abc"의 경우 아스키 코드 문자열이다. 유니코드 문자열은 앞에L을 붙여주어야 한다. 예를들어 L"abc"가 유니코드 문자열이다.


windows.h에 재정의 되어있는 WCHAR은 wchar_t이다.


유니코드는 코딩하기도 쉽고 한글도 표현할 수 있기때문에 이제는 유니코드를 사용해야 겠다.


덧글|덧글 쓰기|신고