1, 문자 집합

 문자 표현 집합은 크게 아래처럼 볼 수 있습니다.

  • SBCS(Single-Byte-Character Set) : 1byte(0~255)로 표현되는 문자 집합

    • ASCII코드(7비트:0x00~0x7F)가 이에 해당하고 8비트 확장코드는 각 나라에서 사용하는 언어마다 조금씩 다르다.
    • 1byte 문자 표현 문화권에서 사용
    • \0(널문자) 1byte
  • MBCS(MultiByte-Character Set) : 1byte이상 문자 집합

    • 윈도우즈 계열에서는 DBCS(Double-Byte Character Set)을 사용하여 1, 2byte(0~655235)로 문자를 표현
    • 1byte이상 문자 표현이 필요한 문화권에서 사용하고 0x00~0x7F는 ASCII코드와 같고 나머지는 각 나라마다 다름
    • \0(널문자) 1byte
  • UCS(Universal Character Set) : 전 세계의 문자를 모두 표현할 목적으로 만들어진 국제 표준 문자 집합. 1byte 이상으로 표현

    • 유니코드(UNICODE)가 이에 해당하고 윈도우즈 계열은 UTF-16으로 인코딩(UTF : Unicode Transformation Format). \0(널문자) 2byte
    • 대표적인 유니코드

      • UTF-8 : 1,2,3,4byte로 인코딩
      • UTF-16 : 2byte로 인코딩
      • UTF-32 : 4byte로 인코딩

 

 

2, Microsoft의 C/C++ 컴파일러와 문자 집합

우리나라도 영어 문화권이 아닌 관계로 MBCS를 사용하거나 UNICODE를 사용합니다. 컴파일 옵션에서 간단하게 바꿀 수 있습니다.

  • MBCS의 특징

    • 1byte의 문자를 많이 사용한다면 메모리를 절약할 수 있다.
    • 국제화에 사용될 수 없습니다.(다른 문화권의 문자를 표현할 수 없습니다.)
    • 문자 크기가 일정하지 않으므로 문자 처리속도가 느릴 수 있습니다.
  • UNICODE의 특징

    • 모든 문자를 2byte로 표현하므로 처리 속도가 빠릅니다.
    • 국제화에 사용될 수 있습니다.(다른 문화권의 문자를 표현할 수 있습니다.)

 

요즘 만들어지는 대두분의 프로그램은 UNICODE를 사용합니다.

만약 MBCS를 사용하는 프로그램으로 만들 경우, 국제화를 위해서 컴파일 옵션만 바꾸면 UNICODE로 컴파일되도록 코드를 작성합니다.

컴파일 옵션은 단지 UNICODE, _UNICODE 매크로를 추가하는 것뿐입니다.

컴파일 옵션 설정은 아래와 같습니다.

 

VC++2008의 _MBCS와 _UNICODE 설정 속성 페이지의 '구성 속성'의 '문자 집합'을 선택합니다.

 Unicode_설정.png

두 설정을 바꾸면 아래처럼 컴파일 옵션 설정이 바뀌게 됩니다.

_MBCS로 설정

Unicode_설정(_MBCS).png 

 

_UNICODE로 설정

Unicode_설정(_Unicode).png

 유니코드로 설정하면 _UNICODE와 UNICODE 옵션이 모두 포함됩니다. C런타임 라이브러리의 전처리 매크로는 _UNICODE를 윈도우 라이브러리는 UNICODE를 필요로 하기 때문입니다.

 

3, MBCS, UNICODE 문자와 문자열 코드

 

MBCS 문자와 문자열 예제입니다.

#include <stdio.h>

void main( )
{
    char c = 'A';
    char *str= "ABC";

    printf("%c\n", c);
    printf("%s\n", str);
}
  1. A
    ABC

 지금까지 배운 내용처럼 출력하면 MBCS 방식 문자, 문자열 출력입니다.

 

UNICODE 문자와 문자열 예제입니다.

#include <stdio.h>

void main( )
{
    wchar_t c = L'A';
    wchar_t *str= L"ABC";

    wprintf(L"%c\n", c);
    wprintf(L"%s\n", str);
}
  1. A
    ABC

 모든 유니코드 문자와 문자열은 L자를 붙입니다. 또 2byte의 문자를 저장하기 위해 wchar_t라는 자료형(unsigned short형과 같은) 변수에 저장합니다. 함수는 printf() 대신 wprintf()를 사용합니다.

 

만약 컴파일 옵션을 사용하여 MBCS와 UNICODE에 따라 코드를 변환하려면 호환가능한 type과 문자열을 사용하면 됩니다.

#include <stdio.h>
#include <tchar.h>

void main( )
{
    TCHAR c = _T('A');
    TCHAR *str= _T("ABC");

    _tprintf(_T("%c\n"), c);
    _tprintf(_T("%s\n"), str);
}
  1. A
    ABC

#include <tchar.h>를 포함하고 자료형을 TCHAR로 합니다. 문자나 문자열은 _T()나 _TEXT()로 감쌉니다. 함수는 _tprintf()로 바꿉니다.

이제 위 코드는 컴파일 옵션에 따라 MBCS나 UNICODE로 컴파일됩니다.

 

4, 주요 매크로 정의

실제 TCHAR와 _T(), _tprintf()의 정의를 볼까요?

#include <stdio.h>
#include <tchar.h>

#ifdef  _UNICODE
  typedef wchar_t     TCHAR;
  #define _T(x)      L ## x
  #define _tprintf        wprintf
#else
  typedef char            TCHAR;
  #define _T(x)      x
  #define _tprintf        printf
#endif

 컴파일 옵션을 설정하면 _UNICODE라는 매크로가 컴파일 옵션에 정의되며 매크로 정의 여부에 따라 문자와 문자열 처리가 달라지는 것을 볼 수 있습니다.

 

 5, PSTR, PCSTR  : PWSTR, PCWSTR : PTSTR, PCTSTR

 

마지막으로 windows.h(winnt.h)에는 사용 편의를 위해 여러가지 typedef와 define이 정의되어 있습니다.

 

char* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    char *str= "ABC";
}
void main( )
{
    CHAR *str= "ABC";
}
void main( )
{
    PCHAR str= "ABC";
}
void main( )
{
    PSTR str= "ABC";
}

 위 main()은 모두 같은 코드입니다.

 

 const char* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    const char *str= "ABC";
}
void main( )
{
    const CHAR *str= "ABC";
}
void main( )
{
    const PCHAR str= "ABC";
}
void main( )
{
    PCSTR str= "ABC";
}

 위 main()은 모두 같은 코드입니다.

 

 wchar_t* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    wchar_t *str= L"ABC";
}
void main( )
{
    WCHAR *str= L"ABC";
}
void main( )
{
    PWCHAR str= L"ABC";
}
void main( )
{
    PWSTR str= L"ABC";
}

 위 main()은 모두 같은 코드입니다.

 

 const wchar_t* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    const wchar_t *str= L"ABC";
}
void main( )
{
    const WCHAR *str= L"ABC";
}
void main( )
{
    const PWCHAR str= L"ABC";
}
void main( )
{

    PCWSTR str= L"ABC";
}

 위 main()은 모두 같은 코드입니다.

 

 TCHAR* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    TCHAR *str= TEXT("ABC");
}
void main( )
{
    PTCHAR str= TEXT("ABC");
}
void main( )
{
    PTSTR str= TEXT("ABC");
}

 

 

 const TCHAR* 예제입니다.

#include <stdio.h>
#include <windows.h>

void main( )
{
    const TCHAR *str= TEXT("ABC");
}
void main( )
{
    const PTCHAR str= TEXT("ABC");
}
void main( )
{
    PCTSTR str= TEXT("ABC");
} 

 위 main()은 모두 같은 코드입니다.

출처 : http://blog.daum.net/coolprogramming/87

Posted by pkss
,