ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C/C++] [MFC] TCHAR, wchar, char란 무엇인가??
    C_C++ 프로그래밍 2019. 6. 29. 17:15

     

         로재의 개발 일기      

    IOCP를 github에서 예제를 보면서 공부를 하다가

    TCHAR나 _tmain _tprint _wchar_t 와 같은 부분에서 막혀

    저와 같은 분들이 있을까해서 포스팅을 합니당... (win32 공부해야 하나..)


    TCHAR?

    TCHAR를 설명하기 전에, 아스키 코드에 이어

    멀티바이트와 유니코드에 대해서 설명할 필요가 있다.


    1. 아스키 코드 (ASCII)

    아스키 코드 값이라는 말을 프로그래밍을 하다보면 들어봤을 것이다.

    (비록 이제 시작했더라도)

    이는 영어, 부호, 숫자등을 128개의 수로 나타내는 방법을 사용한다.

    아스키코드는 1byte의 크기 (0000 0000~ 1111 1111)를 가지게 되지만, 이 ASCII CODE를 가지고는 한글이나 다른 언어를 표현할 수 없다.

    (한글은 2바이트이기 때문에...)


    2. 멀티바이트 코드 (MBCS)

    그래서 나온 것이 멀티바이트 코드이다.

    모든 문자는 2byte의 크기를 가진다.

    하지만 이 방법으로는 종종 한글이나 일어가 깨지는 현상을 볼 수 있는데,

    이는 윈도우가 멀티바이트 기법을 사용하고는 있지만, 세계 표준은 아니기 때문이다.


    3. 유니코드 (Unicode)

    유니코드를 세계 표준으로 2byte 크기를 가지고 있고, 굳이 분류하라면

    멀티바이트 코드인 것이 당연하다.


    그런데 왜 Visual studio에서는 멀티 바이트와 유니코드를 구분하라고 하는 것일까?

    지금까지 알아본 결과로는 MBCS은 세계 표준이 아닌 윈도우에서 개발된 코드이기 때문이다.


    그렇다면..?

    프로그램을 단순히 혼자 사용한다면 상관이 없겠지만
    게임도 프로그램도 그리고 그 소스코드 마저도 git에서 공유되는 세상에
    내 소스코드가 일어로 프랑스어로 중국어로 사용이 될 수 있다면 얼마나 좋겠는가?
    (개발에 유연성이 필요한 셈이다)
    그래서 유니코드를 사용하는 셈이다.

    이때 VS에서 유니코드를 사용하기 위해서는
    우리가 일반적으로 알고 있는
    char나 printf가 아닌 wchar wprintf로 변환해줄 필요가 있다.


    이는 tchar 헤더파일에서 매크로 정의를 도와준다.

    대강 보면 유니코드를 정의하면 _TCHAR는 wchar_t로 재정의 된다는 것을 알 수 있다.

    (음.. 잘은 모르겠지만 이런 느낌..)


     MBCS 예제

    단순하게 문자열을 출력하는 예제이다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include "Windows.h"
    #include<stdio.h>
    #include<tchar.h>
     
    using namespace std;
     
    int main(void) {
        _TCHAR str[] = "안녕하세요2019";    
        _tprintf("%s\n", str);
        _tprintf("%d"sizeof(str));
        system("pause");
        return 0;
    }
    cs

    이때 #include<tchar.h>에서

    UNICODE를 정의해주면 그에 맞게 수정을 해주지만

    지금과 같이 정의를 해주지 않은 상태에서는

    우리가 알고 있는 일반적인 프로그래밍 기법과 같다.

    MBCS에서는 숫자는 1바이트 처리 한글은 2바이트 처리를 하기 때문에

    15바이트의 크기를 가진다는 것을 출력 결과 알 수 있었다. ('\n'포함)

    _TCHAR를 char로 정의하고 있다. (tchar 헤더파일에서)



      Unicode 예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include "Windows.h"
    #include<stdio.h>
    #include<tchar.h>
    #include <locale.h>
     
    #define _UNICODE
     
    using namespace std;
     
    int main(void) {
        setlocale(LC_ALL, "KOREAN");
        _TCHAR str[] = _T("안녕하세요2019");    // unicode 기반
        _tprintf(_T("%s\n"), str);            // 한글 가능
        _tprintf(_T("%d\n"), sizeof(str));
        setlocale(LC_ALL, "C");            // default로 변환
        _tprintf(_T("%s\n"), str);            // 한글이 안된다.
        _tprintf(_T("%d\n"), sizeof(str));
        system("pause");
        return 0;
    }
    cs

    이제 #define _UNICODE로 유니코드를 정의했다.

    UNICODE는 모든 문자를 2바이트로 처리하기 때문에

    2 * 10 = 20의 size를 가지고 있음을 알 수 있다. ('\n'포함)

    또한 유니코드를 형식에 맞게 출력하기 위해서 L을 붙여준다. (수정 6.29)

    멀티바이트 코드와 유니코드 둘 다 모두를 만족시키기 위해서 _T를 사용합니다.



    _TCHAR가 wchar_t로 정의가 된 것을 볼 수 있다.

    또한 UNICODE로 한글을 출력하기 위해서는 (알아본 결과)

    locale함수를 사용해야 한다고 한다.



    마무리

    MS는 왜 unicode를 쓰지 왜 MBCS을 사용할까? (비즈니스적인 사유가 있지 않을까?)

    우리가 문성 작성하는 한글이 삼성의 훈민정음과 경쟁하여 이긴 이유 중 하나가

    '뷁' 이나 '잏'과 같은 문자가 출력이 안됐기 때문이라고 한다.

    기술은 역시 돈을 따라가는 것 같다.

    그리고 프로그램으로 돈을 번다는 것은

    그만큼 힘든 것 같다..


    관련글

    ※ 본 글은 개인 포트폴리오 혹은 공부용으로 사용하기 때문에, 무단 복사 유포는 금지하지만, 개인 공부 용도로는 얼마든지 사용하셔도 좋습니다


    반응형
Designed by Tistory.