메뉴 건너뛰기


Developer > Application

C,C++ Wide character

2013.12.28 03:08

푸우 조회 수:17298



최근 C: A reference manaual 번역본을 사서 보고 나서 Wide charater 에 대해서 탐구하기 시작했습니다. C 언어 자체에서 Wide character의 자료형인 wchar_t 형을 지원해 준다길래, 한글을 사용하기 편해지겠거니 하고 한번 테스트를 해볼 겸 해서 소스를 한번 짜 봤습니다.

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
    wchar_t *string = L"테스트 문자열입니다.";
    wprintf("%s", string);
    return 0;
}


이 소스로를 컴파일 하는데. 처음 할 때는 컴파일이 되고, 그후에는 컴파일시에 converting to execution character set 에러가 나는 겁니다. 이 문제를 해결하기 위해 레퍼런스를 뒤지고, 인터넷도 한참 뒤졌습니다. 그러기를 일주일.. 이주일이 지나서야. 원인을 알았습니다. 원인은 gcc 는 광역문자 사용시 소스 코드의 인코딩이 ascii 또는 UTF-8 인 경우에만 해당 문자열을 광역문자로 변환할수 있던 것이었습니다. OTL.. (참고로 윈도우는 현재 로케일을 참조하여 컴파일시 자동으로 현재 문자셋에서 광역문자로 변환, 저장합니다.)
이제 이 문제를 해결하자, 해당 컴파일을 하고 나서 실행을 하고 났더니, 잘 출력이 되는걸 확인 할 수 있었습니다. 그러나, 인코딩이 다른 터미널에서 실행을 하니, 글자가 깨져나오는 것을 알 수 있었습니다. 분명 광역문자가 해당 터미널 문자셋으로 변경되서 출력되는 것이 잘 안되는 모양입니다. 그래서 로케일을 한번 응용해 봤습니다.

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

int main()
{
    setlocale(LC_CTYPE, "");
    wchar_t *string = L"테스트 문자열입니다.";
    wprintf(L"%ls", string);
    return 0;
}


위의 코드에서 setlocale 은 프로그램이 사용할 로케일을 설정해 주는 부분입니다. LC_CTYPE 은 문자셋을 설정해 주는 것입니다. 그리고 두번째 인자로 ""가 주어졌는데, 이는 프로그램이 실행시 로케일읠 사용하겠다는 것입니다. 이렇게 지정함으로써, 프로그램 실행시, 프로그램 내부의 광역문자열이 해당 로케일에 맞는 문자열로 변환되어 출력되게 됩니다. 물론 이때에도, 한글을 썼는데, 일본어 문자셋에서 한글이 보인다던가 할리는 만무합니다. 이주간 삽질하면서 겨우 광역문자 핸들링에 대해 기본을 갖췄습니다. 이제 앞으로 이점을 주의하면, 광역문자 사용도 할만은 하겠습니다.
PS. 참고로, 책을 보면서 깨달은 점은, C 언어에서 스트림이 열리고, 처음 입출력시, 어떠한 입출력을 쓰느냐에 따라, 일반 입출력 함수가 사용되거나 광역문자열 입출력 함수가 사용 된다는 것을 알게 되었습니다. 만약 스트림을 열고 광역문자 입출력 함수를 쓰고, 그 다음에 일반 입출력 함수를 쓰게 되면 뒤에 사용된 일반 입출력 함수는 무시되게 된다는 것을 알게 되었습니다. 이를 번갈아 사용하려면 특정 함수(기억이 안나서 -_-a)를 써서, 해당 상태를 초기화 혹은 반대상태로 바꾼 후에 사용해야 합니다.