2바이트 이상의 문자를 문자를 저장하기 위해 wchar_t 변수를 사용한다.
물론 char * 로 저장할수도 있다.

wchar_t 는 typedef unsigned long (리눅스) 혹은 short(윈도우) 형이다.

리눅스에서는 4바이트이고 윈도우에서는 2바이트이다.

왜 wchar_t 를 사용하는가?

만약 char * 형으로 문자열(UTF-8 방식)을 저장한다고 하면,
"가" 란 글자는 EA B0 80 (16진수) 형태로 저장된다.
즉,
char *pHangul = "가"; 라고 선언하면,
pHangul[0] -> 0xEA;
pHangul[1] -> 0xB0;
pHangul[2] -> 0x80;

가 저장된다.

이 상태에서 만약 알파벳과 한글을 혼용하면, 영어는 1바이트 한글은 3바이트 이므로, 한글과 영어를 구분하여 사용하기가 상당히 난해한 상황이 온다.
일일이 최상위 비트를 검사해서 '1' 인지 확인한후 '1' 이면 뒤에 2바이트를 더 읽어들이는 작업을 해야 한다.
잘못 계산하면 3바이트중 엉뚱한 곳부터 시작하게 되면 엉뚱한 결과가 나오게 된다.

wchar_t 를 사용하면 한글과 영어에 상관없이 wchar_t 하나당 하나의 문자가 저장된다.
예를 들어 wchar_t *pw = L"ab가나"; 라고 하면 
pw[0] -> 'a';
pw[1] -> 'b';
pw[2] -> '가';
pw[3] -> '나';

이런식으로 저장이 된다. 그러므로 굳이 최상위 비트를 비교하지 않아도 된다.

char * 이런식으로 저장되는 형식을 Multi Byte String 이라고 하며
wchar_t 에 저장되는 형식을 Wide Character String 이라고 한다.

wchar_t 사용하기

wchar_t 는 일반적으로 유니코드 형식으로 저장된다.
문자열을 대입하기 위해서는 접두어 "L" 을 붙여준다.

wchar_t *str = L"한글";

이런식으로 사용한다.

wchar_t 를 다루는 표준함수가 있다.

기본적으로 C 의 char * 문자 관리 함수와 같다. 대신 str 대신 wcs 를 적어주면 된다.
strlen -> wcslen
strcpy -> wcscpy
...

wchar_t 를 출력하기위해서는 wprintf 또는 fputws 함수를 사용하면 된다.

리눅스에서는 wprintf 를 사용하면 printf 와 같이 사용할 수 없다.

wchar_t 와 char 변환

만약 소켓통신을 한다고 할때,
테이터를 wchar_t 로 받는 것보다 char * 로 받아서 형변환을 해주는게 손쉬울 것이다.
데이터를 전송할때도 wchar_t 를 char * 로 바꿔서 전송해주는것이 호환성을 위해 좋을 것이다.
(프로그램간에 프로토콜이 정해져 있으면, wchar_t 든 char 든 크게 상관은 없다.)

wchar_t 를 char 로 변환하려면 함수를 사용하면 된다.
char 를 wchar_t 로 변환하려면 mbstowcs 함수를 사용하면 된다.


리눅스 GCC vs VC++

리눅스에서 wchar_t 를 wprintf 로 출력하기 위해서는 몇가지 세팅이 필요하다.
리눅스에서는 여러가지 한글 인코딩을 사용할 수 있는데, 여기서는 utf8 을 기준으로 설명하도록 하겠다.

리눅스 콘솔 세팅이 UTF-8 로 되어 있는지 확인한다.
그리고 LANG 환경변수가 ko_KR.utf8 로 되어 있는지 확인한다.
ko_KR.eucKR 로 되어 있다면 ko_KR.utf8 로 바꿔준다.
바꾸게 되면 한글로 된 것들이 깨져 보일수 있다.
(어디까지나 UTF-8 테스트용이므로 그냥 넘어가도록 한다.)

그리고 wprintf(L"한글"); 을 이용해서 제대로 출력되는지 확인해 본다.
만약 제대로 나오지 않는다면,
setlocale(LC_ALL,"ko_KR.utf8); 을 추가해 준다.

VC++ 에서는 이상하게 wchar_t 로 선언된 "가나다" 란 문자열을 wcslen 으로 보면 길이가 6으로 나온다.

길이가 3으로 나오게 하려면
setlocale(LC_ALL,".949");
를 추가해 준다.

참고자료
[1] UTF-8  http://ko.wikipedia.org/wiki/UTF-8
[2] wchar_t http://www.killrain.net/channel/lab/?subject=C%2B%2B%EC%9D%98+%EB%8B%A4%EC%96%91%ED%95%9C+string+%ED%83%80%EC%9E%85&mode=view
[3] wprintf http://kldp.org/node/79934

+ Recent posts